DSP 芯片的定点数的表示及运算,不会运用Q格式的DSP程序员不是优秀的程序员!,定点处理器不能直接处理小数 举例:,表达精度为0.01Hz的频率变量f,处理小数的方法有三种: 1)定义为float型C语言的‘抹平’作用,编程工作量小,编译后的代码长,运算速度慢,但精度高 2)仍定义为整型(int或long),采用放大若干倍数来表示小数比如100倍,若改为0.001Hz呢? 3)仍定义为整型(int或long),采用定标法来确定小数1、 数的定标,由程序员来确定一个数的小数点处于16位或32位中的哪一位 常用Q格式来表示数的定标浮点数和定点数之间的转换公式:,浮点数转换为定点数: xq=(int)(xf*2Q) 定点数转换为浮点数: xf=(float)(xq *2-Q) 浮点数1.1转换成16位定点数Q13格式 xq=(int)(1.1*213) =(int)9011.2=9011=2333h,2、16位数的定标,1)16位有符号数的定标 计算机采用2的补码存储有符号数每个16位数用一个符号位表示数的正负,其余15位表示数值的大小最高位是符号位,Q0-Q15 2)16位无符号数的定标 没有符号位,都是正数,Q0-Q16,理论上可以用Q16表示精度更高的小数,但常用Q15,原因: 简化,既可表示有符号又可表示无符号,Q15精度已足够; 防止变量以后变为有符号,留有余地。
表1 Q表示、S表示及数值范围,从上表可以得知:,1)Q值越大,数值范围越小,但精度越高,范围与精度是一对矛盾; 2)同样一个16位数,若小数点设定的位置不同,它所表示的数也不同 2000H = 8192; Q0 而 2000H = 0.25 ; Q15,,以上是对16位来讲的,对于32位,定标表示的小数精度是一样的,但其整数范围不一样 有符号 32位的Q15格式表示的范围为 -65536≤X ≤65535.9999695,3、Q15格式,程序中最常用的是Q0和Q15格式,小数之间相互做乘 法仍是小数,永远不会溢出 int a,b; //Q15 int c; //Q15 c=((long)a*b)15; //一定要有“(long)” TI公司的例程中的变量都使用了Q格式,甚至还给出了 一个Q 格式数据库qmath.lib,包含倒数,正弦运算, 可以免费下载C54x采用2的补码表示小数,其最高位为符号位,数值范围从-1~1一个16位2的补码小数(Q15格式)的每一位的权值为: MSB(最高位) … LSB(最低位) -1. 1/2 1/4 1/8 … 2-15 一个十进制小数乘以32768之后再将其十进制整数部分转换成十六进制数,就能得到这个十进制小数的2的补码表示了。
≈1 → 7FFFh 0.5 正数:乘以32768 4000h 0 → 0000h -0.5 负数:其绝对值部分乘以32768,再取反加1 C000h -1 8000h,,通过合适的Q格式,可以把数值根据所需的精确度做适当地转换,以便定点数的DSP也可以处理高精度的浮点数下面以Q15为例,说明转换的过程 1) 先确定准备转换的十进制数值N,是在Q15格式的数值范围之间,即-1.000000≤N≤+0.999997 2)数值N乘以215,即N'=N×215=N×32768 3)把步骤2)的结果加216,即N''=N'+216=N'+65536 4)步骤3)的结果转换成十六进制,并把第17位舍弃掉,得到的结果就是N的Q15转换值下面通过把-0.2345及+0.2345转换成Q15格式来说明转换方法 -0.2345的转换为: -0.2345×32768=-7684.1≈-7684 -7684+65536=57852 57852转换成十六进制数值为0E1FCh,所以结果为E1FCh。
+0.2345的转换为: 0.2345×32768=7684.1≈7684 7684+65536=73320 73320转换成十六进制数值为11E04h,并把第17位舍弃掉,结果为1E04hQ15定点小数乘法运算 两个16位整数相乘,乘积总是“向左增长”,这就意味着多次相乘后乘积将会很快超出定点器件的数据范围而且要将32位乘积保存到数据存储器,就要耗费两个机器周期以及两个字的程序和RAM单元然而,两个Q15的小数相乘,乘积总是“向右增长”,这就意味着超出定点器件数据范围的将是不太感兴趣的部分以字长为4位和8位累加器为例,先看一个小数乘法的例子 0 1 0 0(0.5→23×0.5=(4)10=(0100)2) × 1 1 0 1(-0.375→23×(-0.375)=(-3)10 0 1 0 0 =(1101)补) 0 0 0 0 0 1 0 0 1 1 0 0 (-0100) 1 1 1 0 1 0 0 (-0.1875=-12/26←-12=(1110100)补),上述乘积是7位,当将其送到8位累加器时,为保持乘积的符号,必须进行符号位扩展,这样,累加器中的值为11110100(-0.09375=-12/27),出现了冗余符号位。
原因是: S x x x (Q3) × S y y y (Q3) S S z z z z z z (Q6格式) 即两个带符号数相乘,得到的乘积带有2个符号位,造成错误的结果 同样,对于两个十六位数相乘,乘积只有30位,在最高的两位也是符号位,同样会造成错误的结果小数乘法与冗余符号位,,解决冗余符号的办法是:在程序中设定状态寄存器ST1中的FRCT(小数方式)位1,在乘法器将结果传送至累加器时就能自动地左移1位,累加器中的结果为:Szzzzzz0(Q7格式),即11101000(-0.1875=-24/27←-24=(11101000)补),自动地消去了两个带符号数相乘时产生的冗余符号位所以在小数乘法编程时,应当事先设置FRCT位: SSBX FRCT … MPY *AR2,*AR3,A STH A,@Z 这样,C54x就完成了Q15*Q15=Q15的小数乘法2 基于C语言的定点运算的基本原理,2.1加法/减法运算 必须保证两个操作数的定标值一样; 小数点的调整,Q 值小的调整; 1.结果不超过16位表示范围 设x的Q值为Qx,y的Q值为Qy,且QxQy,加法/减法结果z的定标值为Qz,则,,z=x+y ,,,,,,=,=,,所以定点加法可以描述为: int x,y,z; long temp; /*临时变量*/ temp=y(Qx-Qz)), 若Qx≥Qz z=(int)(temp(Qz-Qx)), 若Qx ≤ Qz,,设x=0.5,y=3.1,则浮点运算结果为z=x+y=0.5+3.1=3.6; Qx=15,Qy=13,Qz=13,则定点加法为: x=16384;y=25395; temp=253952)=29491; 因为z的Q值为13,所以定点值z=29491即为浮点值z=29491/8192=3.6。
设x=3.0,y=3.1,则浮点运算结果为z=x-y=3.0-3.1=-0.1; Qx=13,Qy=13,Qz=15,则定点减法为: x=24576;y=25295; temp=25395; temp=x-temp=24576-25395=-819; 因为QxQz,故 z=(int)(-8192)=-3276由于z的Q值 为15,所以定点值z=-3276即为浮点值z=-3276/32768-0.12.结果超过16位表示范围,设x的Q值为Qx,y的Q值为Qy,且QxQy,加法结果z的定标值为Qz,则定点加法为: int x,y; long temp,z; temp=y(Qx-Qz),若Qx≥Qz z=temp(Qz-Qx),若Qx≤Qz,,设x=15000,y=20000,则浮点运算值为z=x+y=35000,显然z32767,因此 Qx=1,Qy=0,Qz=0,则定点加法为: x=30000;y=20000; temp=200001=35000; 因为z的Q值为0,所以定点值z=35000就是浮点值,这里z是一个长整型数2.2 乘法运算,设浮点乘法运算的表达式为: float x,y,z; z = xy; 假设经过统计后x的定标值为Qx,y的定标值为Qy,乘积z的定标值为Qz,则 z = xy = ,,,,,=,,所以定点表示的乘法为: int x,y,z; long temp; temp = (long)x; z = (temp×y) (Qx+Qy-Qz);,,定点乘法 设x = 18.4,y = 36.8,则浮点运算值为z =18.4×36.8 = 677.12; 根据上节,得Qx = 10,Qy = 9,Qz = 5,所以 x = 18841;y = 18841; temp = 18841L; z = (18841L*18841)(10+9-5) = 354983281L14 = 21666; 因为z的定标值为5,故定点 z = 21666即为浮点的 z = 21666/32 = 677.08。
2.3除法运算,设浮点除法运算的表达式为: float x,y,z; z = x/y; 假设经过统计后被除数x的定标值为Qx,除数y的定 标值为Qy,商z的定标值为Qz,则 z = x/y = ,,,,,所以定点表示的除法为: int x,y,z; long temp; temp = (long)x; z = (temp(Qz-Qx+Qy))/y;,,定点除法 设x = 18.4,y = 36.8,浮点运算值为z = x/y = 18.4/36.8 = 0.5; 根据上节,得Qx = 10,Qy = 9,Qz = 15;所以有 x = 18841, y = 18841; temp = (long)18841; z = (18841L(15-10+9))/18841 = 308690944L/18841 = 16384; 因为商z的定标值为15,所以定点z = 16384即为浮点 z = 16384/215= 0.5。