首页 > 编程知识 正文

学前端还是学java,python编程计算器

时间:2023-05-03 12:41:42 阅读:151086 作者:1232

介绍

本APP注释介绍如何使用ARM C编译器和ARM或精简程序集创建高效的指向算术代码。 因为ARM核心是整数处理器,所以必须用整数运算模拟所有浮点运算。 使用定点算法而不是浮点数可以大大提高许多算法的性能。

本文档包含以下部分:

定点运算原理:描述了定点运算所需的数学概念。

例如:给出了为了信号处理和图形处理而制作定点代码的例子。 这是两种最常见的用途。

C编程:涵盖了在c中实现定点代码的实际细节。 示例程序与一组宏定义一起提供。

汇编程序:介绍汇编程序的示例。

定点算法原理

在计算数学中,可以使用一对整数(n,e ) (尾数和指数)来近似表示分数。 这是整数,表示分数n2en2e。 指数e可以认为在放置二进制小数点之前必须移动n的位数。 例如

我是Mantissa(n )

是exponent(e )

伯尼

最差

01100100

-1

011001000.

200

01100100

0

01100100.

100

01100100

1

0110010.0

50

01100100

2

011001.00

25

01100100

3

01100.100

12.5

01100100

7

0.1100100

0.78125

如果e是变量,保存在寄存器中,并且在编译时未知,则(n,e )称为浮点数。 如果事先知道e的话,在编译时,(n,e )被称为固定点数。 通过存储尾数,可以将固定点数存储在标准整数变量(或寄存器)中。

关于常数点,指数e通常用字母q表示。 以下各节介绍如何对两个常量执行基本算术运算。 两个算术是a=n2pa=n2p和b=m2qb=m2q,结果表示为c=k2rc=k2r。 其中p、q和r是固定的常数指数。

计算时,只需通过尾数n m的两个计算得到k。 在其中使用他们的指数进行转换。 实际存储数字时也只存储尾数。 指数由另一个对应的数字保存。

指数变化

对定点数执行的最简单的操作是改变指数。 为了将指数从p变为r (执行操作c=a ),可以通过简单的移位根据n计算随机数k。

因为n2p=n2rp2r n2p=n2rp2r

k=n=p(if ) r=p ) ) ) ) )。

k=n(pr ) k=n ) pr ) if ) pr ) if(pr ) )

加法和减法

要进行c=a b的操作,首先将a和b变换为与c相同的指数r,然后加上尾数。 这个方法如下。

N2RM2R=(NM ) N2RM2R=(NM ) 2R

减法相似

乘法

乘积c=ab可以通过简单的整数乘法来执行。 等式如下。

ab=N2PM2q=(nm )2) ) PQ ) ab=N2PM2q=(nm ) 2(pq ) ) ) ) ) 65

因此,积n * m是指数p q的答案的尾数。 要将答案转换为指数r,请按上述方式进行移位。 例如

k=(nm ) ) pQR ) k=(nm ) ) pQR ) if ) pq=r ) if ) pq=r )

除法

c=a/b也可以通过简单的整数除法来执行。 公式如下。

a/b=(N2P )/M2Q ) ) n/m ) 2qp=) n/m ) 2r qp2ra/b=(n2p )/M2Q ) ) n/m ) 2rqp2r )

为了不丢失精度,必须在除以m之前执行2r qp2r qp乘法。 例如,

k=(n=p ) if ) rq=p ) )。

平方根

平方根的公式如下。

a=N2P=N22RP2ra=N2P=N22RP2R

换句话说,isqr是整数的平方根函数(例如,c=ac=a执行isqr(n2RP ) k=isqr ) n2RP )。

溢出

上述等式显示了对定点形式的数字只使用整数运算来执行加、减、乘、除、根提取的基本操作的方法。 但是,为了将答案准确存储在2r2r ()表示的结果中,必须确保在计算过程中不会发生溢出。 如果没有仔细选择指数,则每次左移时,加/减或乘法都会溢出,成为没有意义的答案。

以下“现实世界”示例说明了如何选择指数。

实例

信号处理

在信号处理中,数据通常由-1到1之间的分数组成。

此示例使用指数q和32位整数尾数(以便每个值可以保存在一个ARM寄存器中)。 为了能够将两个数字相乘而不会溢出,您需要2q<32或q<=15。 在实践中,通常选择q = 14,因为这允许与几个积累相乘而没有溢出风险。

在编译时固定q = 14。 然后0xFFFFC000表示-1,0x00004000表示+1和0x00000001表示2−142−14,最精确的除数。

假设x,y是两个q = 14尾数,n,m是两个整数。 通过应用上面的公式,您可以得到基本操作,其中 a 为正常的整数:

Operation

Code to produce mantissa of answer in q=14 format

x + y

x + y

x + a

x + (a<<14)

xa

x*a

xy

(x*y)>>14

x/a

x/a

a/b

(a<<14)/b

x/y

(x<<14)/y

x−−√x

sqr(x<<14)

图像处理

在这个例子中,(x,y,z)坐标以八位小数信息(q = 8)以小数形式存储。 如果x存储在一个32位寄存器中,那么x的最低字节给出小数部分,最高的三部分是整数部分。

要计算距离原点的距离d,以q = 8的形式:d=x2+y2+z2−−−−−−−−−−√d=x2+y2+z2

如果您直接应用上述公式并将所有中间答案以q = 8的形式保存,则会得到以下代码:

x = (x*x)>>8 square x

y = (y*y)>>8 square y

z = (z*z)>>8 square z

s = x+y+z sum of squares

d = sqrt(s<<8) the distance in q=8 form

1

2

3

4

5

或者,如果您将中间答案保持为q = 16格式,则减少班次数并提高准确度:

x = x*x square of x in q=16 form

y = y*y square of y in q=16 form

z = z*z square of z in q=16 form

s = x+y+x sum of squares in q=16 form

d = sqr(s) distance d in q=8 form

1

2

3

4

5

总结

如果你以q形式相加两个数字,它们将保持q-form。

如果你用q形式乘以两个数字,答案是2q形式。

如果你采用q形式的数字的平方根,答案是q / 2形式。

要从q-form转换为r-form,你需要向左移(r-q)或向右移(q-r),取决于q和r中哪一个更大

要获得最佳精度结果,请选择最大的q,并保证中间计算不能溢出。

C 程序

可以使用标准整数算术运算在C中对定点算术进行编程,并且当需要时(通常在确保答案仍然是q形式之前或之后的操作之前或之后)使用移位来改变q-形式。

为了使编程更容易阅读,已经定义了一组C宏。 下面的示例程序定义了这些宏并说明了它们的用法:

注:编译需要在末尾加上 -lm 选项 ,如gcc fixed.c -o fixed -lm

/* A Simple C program to illustrate the use of Fixed Point Operations */

#include

#include

#include

/* DEFINE THE MACROS */

/* The basic operations perfomed on two numbers a and b of fixed

point q format returning the answer in q format */

#define FADD(a,b) ((a)+(b))

#define FSUB(a,b) ((a)-(b))

#define FMUL(a,b,q) (((a)*(b))>>(q))

#define FDIV(a,b,q) (((a)<

/* The basic operations where a is of fixed point q format and b is

an integer */

#define FADDI(a,b,q) ((a)+((b)<

#define FSUBI(a,b,q) ((a)-((b)<

#define FMULI(a,b) ((a)*(b))

#define FDIVI(a,b) ((a)/(b))

/* convert a from q1 format to q2 format */

#define FCONV(a, q1, q2) (((q2)>(q1)) ? (a)<>((q1)-(q2)))

/* the general operation between a in q1 format and b in q2 format

returning the result in q3 format */

#define FADDG(a,b,q1,q2,q3) (FCONV(a,q1,q3)+FCONV(b,q2,q3))

#define FSUBG(a,b,q1,q2,q3) (FCONV(a,q1,q3)-FCONV(b,q2,q3))

#define FMULG(a,b,q1,q2,q3) FCONV((a)*(b), (q1)+(q2), q3)

#define FDIVG(a,b,q1,q2,q3) (FCONV(a, q1, (q2)+(q3))/(b))

/* convert to and from floating point */

#define TOFIX(d, q) ((int)( (d)*(double)(1<

#define TOFLT(a, q) ( (double)(a) / (double)(1<

#define TEST(FIX, FLT, STR) {

a = a1 = randint();

b = bi = a2 = randint();

fa = TOFLT(a, q);

fa1 = TOFLT(a1, q1);

fa2 = TOFLT(a2, q2);

fb = TOFLT(b, q);

ans1 = FIX;

ans2 = FLT;

printf("Testing %sn fixed point answer=%fn floating point answer=%fn",

STR, TOFLT(ans1, q), ans2);

}

int randint(void) {

int i;

i=rand();

i = i & 32767;

if (rand() & 1) i=-i;

return i;

}

int main(void) {

int q=14, q1=15, q2=7, q3=14;

double fa, fb, fa1, fa2;

int a,b,bi,a1,a2;

int ans1;

double ans2;

/* test each of the MACRO's with some random data */

TEST(FADD(a,b), fa+fb, "FADD");

TEST(FSUB(a,b), fa-fb, "FSUB");

TEST(FMUL(a,b,q), fa*fb, "FMUL");

TEST(FDIV(a,b,q), fa/fb, "FDIV");

TEST(FADDI(a,bi,q), fa+bi, "FADDI");

TEST(FSUBI(a,bi,q), fa-bi, "FSUBI");

TEST(FMULI(a,bi), fa*bi, "FSUBI");

TEST(FDIVI(a,bi), fa/bi, "FSUBI");

TEST(FADDG(a1,a2,q1,q2,q3), fa1+fa2, "FADDG");

TEST(FSUBG(a1,a2,q1,q2,q3), fa1-fa2, "FSUBG");

TEST(FMULG(a1,a2,q1,q2,q3), fa1*fa2, "FMULG");

TEST(FDIVG(a1,a2,q1,q2,q3), fa1/fa2, "FDIVG");

printf("Finished standard testn");

/* the following code will calculate exp(x) by summing the

series (not efficient but useful as an example) and compare it

with the actual value */

while (1) {

printf("Please enter the number to be exp'ed (<1): ");

scanf("%lf", &fa);

printf(" x = %fn", fa);

printf(" exp(x) = %fn", exp(fa));

q = 14; /* set the fixed point */

a = TOFIX(fa, q); /* get a in fixed point format */

a1 = FCONV(1, 0, q); /* a to power 0 */

a2 = 1; /* 0 factorial */

ans1 =0; /* series sum so far */

for (bi=0 ; bi<10; bi++) { /* do ten terms of the series */

int j;

j = FDIVI(a1, a2); /* a^n/n! */

ans1 = FADD(ans1, j);

a1 = FMUL(a1, a, q); /* increase power of a by 1 */

a2 = a2*(bi+1); /* next factorial */

printf("Stage %d answer = %fn", bi, TOFLT(ans1, q));

}

}

return 0;

}

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。