DSP浮点转定点方法总结.doc_第1页
DSP浮点转定点方法总结.doc_第2页
DSP浮点转定点方法总结.doc_第3页
DSP浮点转定点方法总结.doc_第4页
DSP浮点转定点方法总结.doc_第5页
已阅读5页,还剩13页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

目录目录 定点运定点运算算方法方法.3 1.1 数 的 定 标.3 1.2C语言:从浮点到定点.4 1.2.1 加法.4 1.2.2乘法.6 1.2.3除法.7 1.2.4 三角函数运算.8 1.2.5 开方运算.9 1.3 附录.10 1.3.1 附录1:定点函数库.10 1.3.2附录2:正弦和余弦表.28 定点运算方法定点运算方法 1.1 数数 的的 定定 标标 对某些处理器而言,参与数值运算的数就是 16 位的整型数。但在许多情况下,数学运 算过程中的数不一定都是整数。那么,如何处理小数的呢?应该说,处理器本身无能为力。 那么是不是就不能处理各种小数呢?当然不是。这其中的关键就是由程序员来确定一个数 的小数点处于 16 位中的哪一位。这就是数的定标。 通过设定小数点在 16 位数中的不同位置,就可以表示不同大小和不同精度的小数了。 数的定标用 Q 表示法。表 1.1 列出了一个 16 位数的 16 种 Q 表示能表示的十进制数值范围 和近似的精度。 Q 表示精度(近似)十进制数表示范围 Q150.00002 -1X0.9999695 Q140.00005 -2X1.9999390 Q130.0001 -4X3.9998779 Q120.0002 -8X7.9997559 Q110.0005 -16X15.9995117 Q100.001 -32X31.9990234 Q90.002 -64X63.9980469 Q80.005 -128X127.9960938 Q70.01 -256X255.9921875 Q60.02 -512X511.9804375 Q50.04 -1024X1023.96875 Q40.08 -2048X2047.9375 Q30.1 -4096X4095.875 Q20.25 -8192X8191.75 Q10.5 -16384X16383.5 Q01 -32768X32767 表 1.1 Q 表示、S 表示及数值范围 从表 1.1 可以看出,同样一个 16 位数,若小数点设定的位置不同,它所表示的数也就 不同。例如: 16 进制数 2000H8192,用 Q0 表示 16 进制数 2000H0.25,用 Q15 表示 从表 1.1 还可以看出,不同的 Q 所表示的数不仅范围不同,而且精度也不相同。Q 越 大,数值范围越小,但精度越高;相反,Q 越小,数值范围越大,但精度就越低。例如, Q0 的数值范围是-32768 到+32767,其精度为 1,而 Q15 的数值范围为-1 到 0.9999695,精 度为 1/32768 = 0.00003051。因此,对定点数而言,数值范围与精度是一对矛盾,一个变 量要想能够表示比较大的数值范围,必须以牺牲精度为代价;而想提高精度,则数的表示 范围就相应地减小。在实际的定点算法中,为了达到最佳的性能,必须充分考虑到这一点。 浮点数与定点数的转换关系可表示为: 浮点数(x)转换为定点数():xq Q q x2x(int) 定点数()转换为浮点数(x): q x Q q x 2)float(x 例如,浮点数 x=0.5,定标 Q15,则定点数,式中表 q x 16384327685 . 0 示下取整。反之,一个用 Q15 表示的定点数 16384,其浮点数为 163842-15 16384/32768=0.5。 1.2c 语言:从浮点到定点语言:从浮点到定点 下面所描述的几种基本运算是浮点到定点转换中经常遇到的,从中可以体会到一些基 本的技巧和方法。 1.2.1 加法加法 设浮点加法运算的表达式为: float x,y,z; z=x+y; 将浮点加法/减法转化为定点加法/减法时最重要的一点就是必须保证两个操作数的定 标值一样。若两者不一样,则在做加法/减法运算前先进行小数点的调整。为保证运算精度, 需使 Q 值小的数调整为与另一个数的 Q 值一样大。此外,在做加法/减法运算时,必须注 意结果可能会超过 16 位表示,即数的动态范围。如果加法/减法的结果超出 16 位的表示范 围,则必须保留 32 位结果,以保证运算的精度。 1 结果不超过 16 位表示范围 设 x 的 Q 值为 Qx,y 的 Q 值为 Qy,且 QxQy,加法/减法结果 z 的定标值为 Qz,则 zx+y y xz Q q Q q Q q yxz 222 = x yx x Q QQ q Q q yx 222 )( = x yx Q QQ qq yx 22 )( )( )( 22 xz yx QQ QQ qqq yxz 一般情况,我们取 x,y 和 z 的定标值相同,即 Qx = Qy = Qz = Qa 。 所以定点加法可以描述为: short x, y, z ; /Qa z = add (x,y); /Qa 函数 add ( ) 有防饱和机制,如果可以确信 x + y 不会溢出(-215 = z = 215-1) , 可以直接写为 z = x + y . 定点减法: short x, y, z ; /Qa z = sub (x,y); /Qa 函数 sub ( ) 有防饱和机制,如果可以确信 x - y 不会溢出(-215 = z Qy,加法结果 z 的定标值为 Qz,则定点加 法为: int x,y; long temp,z; tempy(Qx-Qz),若 QxQz ztemp(Qz-Qx),若 QxQz 一般情况,我们取 x,y 和 z 的定标值相同,即 Qx = Qy = Qz = Qa 。 所以定点加法可以描述为: int x, y, z ; /Qa z = L_add (x,y); /Qa 函数 L_add ( ) 有防饱和机制,如果可以确信 x + y 不会溢出(-231 = z = 231-1) , 可以直接写为 z = x + y . 定点减法: int x, y, z ; /Qa z = L_sub (x,y); /Qa 函数 L_sub ( ) 有防饱和机制,如果可以确信 x - y 不会溢出(-231 (Qx+Qy+1-Qz); 上式中 x 乘 y 的定标本来应该是 Qx + Qy, 但为了处理方便,函数 L_mult( ) 多乘了一 次 2,因此要再加 1。函数 L_mult ( ) 有防饱和机制,如果可以确信 z = x y 不会溢出(- 231 (Qx+Qy-Qz)。 2. 结果超过 32 位表示范围 这种情况下位数超出了标准 c 语言的数的表示范围,只能用数组来保存变量。 定点乘法可表示为: #define NN_DIGIT unsigned int NN_DIGIT x digits; NN_DIGIT y digits; NN_DIGIT z 2* digits; NN_Mult (z, x, y, digits); 应注意的是以上 32 位乘法都是无符号数操作,如果需要做有符号数乘法,则需要根据 乘数的符号来判断。 例 1 设 x = 18.4,y = 36.8,则浮点运算值为 z =18.436.8 = 677.12; 设 Qx = 10,Qy = 9,Qz = 5,所以 int x = 18841;/Q10 int y = 18841;/Q9 z = L_mult(18841, 18841)(10+9+1-5) = 354983281L14 = 21666; 因为 z 的定标值为 5,故定点 z = 21666 即为浮点的 z = 21666/32 = 677.08。 例 2 设 x = 18.4,y = 36.8,则浮点运算值为 z =18.436.8 = 677.12; #define NN_DIGIT unsigned int 设 Qx = 20, Qy = 20, Qy = 20, 所以 NN_DIGIT x = 18.4 * (120); /Q20 NN_DIGIT y = 36.8 * (120); /Q20 NN_DIGIT z2; /Q20 NN_Mult(z, /Q40 NN_Rshift(z, z, 20, 1); /Q(40-20) 1.2.3 除法除法 1. 32 位除法 设浮点除法运算的表达式为: float x,y,z; z = x/y; 假设经过统计后被除数 x 的定标值为 Qx,除数 y 的定标值为 Qy,商 z 的定标值为 Qz,则 z = x/y = z Q q z 2 y x Q q Q q y x 2 2 q QQQ q q y x z yxz )( 2 所以定点表示的除法为: int x,y,z; z = L_shl(x, (Qz-Qx+Qy) )/y; /Qz 2. 32 位以上的除法 这种情况下位数超出了标准 c 语言的数的表示范围,只能用数组来保存变量。 #define NN_DIGIT unsigned int NN_DIGIT x 2*digits; /Qx NN_DIGIT y digits; /Qy NN_DIGIT z digits; /Qz NN_Lshift(x, x, (Qz-Qx+Qy), 2); NN_Div(z, x, 2*digits, y, digits); 做以上运算是要保证 Qz-Qx+Qy 32, 否则要多次移位来实现;应注意的是以上除法都 是无符号数操作,如果需要做有符号数除法,需要根据被除数和除数的符号来判断。 例 1: 设 x = 18.4,y = 36.8,浮点运算值为 z = x/y = 18.4/36.8 = 0.5; 根据上节,得 Qx = 10,Qy = 9,Qz = 15;所以有 int x = 18841, y = 18841; z = L_shl(x, (15-10+9) )/18841; / 308690944L/18841 = 16384 因为商 z 的定标值为 15,所以定点 z = 16384 即为浮点 z = 16384/215= 0.5。 1.2.4 三角函数运算三角函数运算 1 正弦和余弦 一般求 cos、sin 用查表法,方法是预先定义正弦和余弦表,表的长度及表中各元素的 定标是根据精度要求确定的,精度要求越高,表的长度及元素的定标都可以增加。 余弦表制作步骤: 1)计算 cos(2*pi*t/N),其中 0= t =N-1,N 是 02*pi 之间的采样点数。 2)将以上结果(浮点数)按精度要求定标,如 Q15, 3)建立数组 tab_cosN,将以上结果作为该数组的元素。 正弦表的定义方法同上。附录 2 中给出了余弦表 tab_cos360和正弦表 tab_sin360, 精度是 Q15。 例 1 求 cos(2*pi*x/32), x 是定标为 Qx 的整数 cos(2*pi*x/32) = cos(2*pi *(360* x /32) /360); 程序如下: int u = (L_mult(360, x)/32)%360; /Qx int result; result = tab_cosu; /Qx 例 2 求 cos(x), x 是定标为 Qx 的整数 cos(x) = cos(2*pi*(360*x/(2*pi)/360), 程序如下: int pi_Qx = 3.1415*(1Qx); /Qx int u = (L_mult(360, x) / (2* pi_Qx)%360; /Q0 int result; result = tab_cosu; /Qx 上式中将 pi 定标为 Qx 的定点数。 如何进一步提高精度 一般可以增加表的长度即采样点数来提高精度,但在现有采样情况下,也有办法来提 高精度。方法是求出两采样点之间的斜率,根据当前采样点的位置求出更加精确的值。 t t +1 t ab_cos t t ab_cos t +1 posi t i on 例 3 求 cos(x), x 是定标为 Qx 的整数 int pi_Qx = 3.1415*(10.5 时可以采用拟合的方法。 因此: x abs(x)0.5 y = atan(x) (-0.06)*x.2 + 0.5*x +0.3 0.5abs(x)5 拟合可以调用 matlab 的命令 ployfit 来做,例如: x=start:0.1:stop; y=atan(x); pa=polyfit(x,y,2); 上式中的运算都是简单的乘法运算,较为简单。 1.2.5 开方运算开方运算 浮点开方运算描述为: float x, y; y = sqrt(x); 定点求开方有多种方法,各种方法在收敛速度上不尽相同,下面介绍几种常用的迭代算法。 1Newton-Raphson-Babylonian 算法: 给定整数 N, 求 sqrt(N)。 首先确定初值 x0, 然后利用一个简单的迭代公式: xn+1 = (xn +N/xn)/2 迭代次数的选择: 迭代次数与初值 x0的选取很有关系,x0越接近 sqrt(N), 收敛越快。但总的来说,该 方法收敛较快。缺点是收敛时间不确定。 2确定收敛速度的算法: 该方法描述如下: int sqrt(int x) int test, step; if (x 0) return(-1); if (x = 0) return(0); step = 1= 1; return(test); 以上例子是 32 位开放运算,32 位以上的开方运算可参考附录 1 void fixsqrt(UINT4* a, UINT4* b,int digits), 方法同上。 求开方还可以运用线性拟合的方法,由于曲线变化较快,必须根据自变量的范围分段拟合 才能达到理想的精度。 1.3 附录附录 1.3.1 附录附录 1:定点函数库:定点函数库 /*_ | | | Function Name : L_add | | | | Purpose : | | | | 32 bits addition of the two 32 bits variables (L_var1+L_var2) with | | overflow control and saturation; the result is set at +2147483647 when | | overflow occurs or at -2147483648 when underflow occurs. | | | | Complexity weight : 2 | | | | Inputs : | | | | L_var1 32 bit long signed integer (Word32) whose value falls in the | | range : 0 x8000 0000 = L_var3 = 0 x7fff ffff. | | | | L_var2 32 bit long signed integer (Word32) whose value falls in the | | range : 0 x8000 0000 = L_var3 = 0 x7fff ffff. | | | | Outputs : | | | | none | | | | Return Value : | | | | L_var_out | | 32 bit long signed integer (Word32) whose value falls in the | | range : 0 x8000 0000 = L_var_out = 0 x7fff ffff. | |_| */ Word32 L_add(Word32 L_var1, Word32 L_var2) /*_ | | | Function Name : L_sub | | | | Purpose : | | | | 32 bits subtraction of the two 32 bits variables (L_var1-L_var2) with | | overflow control and saturation; the result is set at +214783647 when | | overflow occurs or at -214783648 when underflow occurs. | | | | Complexity weight : 2 | | | | Inputs : | | | | L_var1 32 bit long signed integer (Word32) whose value falls in the | | range : 0 x8000 0000 = L_var3 = 0 x7fff ffff. | | | | L_var2 32 bit long signed integer (Word32) whose value falls in the | | range : 0 x8000 0000 = L_var3 = 0 x7fff ffff. | | | | Outputs : | | | | none | | | | Return Value : | | | | L_var_out | | 32 bit long signed integer (Word32) whose value falls in the | | range : 0 x8000 0000 = L_var_out = 0 x7fff ffff. | |_| */ Word32 L_sub(Word32 L_var1, Word32 L_var2) /*_ | | | Function Name : add | | | | Purpose : | | | | Performs the addition (var1+var2) with overflow control and saturation;| | the 16 bit result is set at +32767 when overflow occurs or at -32768 | | when underflow occurs. | | | | Complexity weight : 1 | | | | Inputs : | | | | var1 | | 16 bit short signed integer (Word16) whose value falls in the | | range : 0 xffff 8000 = var1 = 0 x0000 7fff. | | | | var2 | | 16 bit short signed integer (Word16) whose value falls in the | | range : 0 xffff 8000 = var1 = 0 x0000 7fff. | | | | Outputs : | | | | none | | | | Return Value : | | | | var_out | | 16 bit short signed integer (Word16) whose value falls in the | | range : 0 xffff 8000 = var_out = 0 x0000 7fff. | |_| */ Word16 add(Word16 var1,Word16 var2) /*_ | | | Function Name : sature | | | | Purpose : | | | | Limit the 32 bit input to the range of a 16 bit word. | | | | Inputs : | | | | L_var1 | | 32 bit long signed integer (Word32) whose value falls in the | | range : 0 x8000 0000 = L_var1 = 0 x7fff ffff. | | | | Outputs : | | | | none | | | | Return Value : | | | | var_out | | 16 bit short signed integer (Word16) whose value falls in the | | range : 0 xffff 8000 = var_out = 0 x0000 7fff. | |_| */ Word16 sature(Word32 L_var1) /*_ | | | Function Name : sub | | | | Purpose : | | | | Performs the subtraction (var1+var2) with overflow control and satu- | | ration; the 16 bit result is set at +32767 when overflow occurs or at | | -32768 when underflow occurs. | | | | Complexity weight : 1 | | | | Inputs : | | | | var1 | | 16 bit short signed integer (Word16) whose value falls in the | | range : 0 xffff 8000 = var1 = 0 x0000 7fff. | | | | var2 | | 16 bit short signed integer (Word16) whose value falls in the | | range : 0 xffff 8000 = var1 = 0 x0000 7fff. | | | | Outputs : | | | | none | | | | Return Value : | | | | var_out | | 16 bit short signed integer (Word16) whose value falls in the | | range : 0 xffff 8000 = var_out = 0 x0000 7fff. | |_| */ Word16 sub(Word16 var1,Word16 var2) /*_ | | | Function Name : L_mult | | | | Purpose : | | | | L_mult is the 32 bit result of the multiplication of var1 times var2 | | with one shift left i.e.: | | L_mult(var1,var2) = shl(var1 times var2),1) and | | L_mult(-32768,-32768) = 2147483647. | | | | Complexity weight : 1 | | | | Inputs : | | | | var1 | | 16 bit short signed integer (Word16) whose value falls in the | | range : 0 xffff 8000 = var1 = 0 x0000 7fff. | | | | var2 | | 16 bit short signed integer (Word16) whose value falls in the | | range : 0 xffff 8000 = var1 = 0 x0000 7fff. | | | | Outputs : | | | | none | | | | Return Value : | | | | L_var_out | | 32 bit long signed integer (Word32) whose value falls in the | | range : 0 x8000 0000 = L_var_out = 0 x7fff ffff. | |_| */ Word32 L_mult(Word16 var1,Word16 var2) /* Computes the square root of a fixpoint number a = square(b).*/ /* length :adigits, b2*digits */ void fixsqrt(UINT4* a, UINT4* b, int digits) /UINT4 stepdigits; UINT4 *step; /UINT4 hdigits*2; /UINT4 testdigits; UINT4 *h,*test; step = (UINT4 *)malloc(digits*sizeof(UINT4); h = (UINT4 *)malloc(2*digits*sizeof(UINT4); test = (UINT4 *)malloc(digits*sizeof(UINT4); / if (x 0) return(-1); if (x = 0) return(0); NN_AssignZero (step, digits); stepdigits-1 = 1= 1; NN_RShift(step, step, 1, digits); free(h); free(test); free(step); /* Computes a = b + c. Returns c

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论