关于IQMATH和浮点数在DSP的深入理解
使用了一段时间IQmath来处理浮点数,发现对其的理解还是不够,只是限于根据其resolution/precison来选取不同的IQ形式来处理浮点数。今天就遇到了一个比较棘手的问题,如果我想把一个整数Uint16型赋给IQ15类型的,发现再转换回整数的时候赋值已经不对了,我通过先将Uint16赋给FLOAT32型,再使用语句,temp=_IQ(float32);(此语句的作用是将浮点类型转换为定点IQ15的格式)发现这样处理后,再换回整数时赋值和原始赋值是相同的。可是,为了一个赋值运算,我将要多申请多少FLOAT32型的变量! 我想一定有办法可以直接赋值,我深入理解了下float32型的构造,float和int都是固定长度的,4字节(32位机子)。int是精确的,超出范围就溢出了。数据错误了。 而float并不是单纯的101010这样存储,是把4个字节划分为 符号位,指数位,尾数位 比如1.123123*10^35;3个部分固定的,因为有指数,存储的范围当然比int大了。 但是3个部分也有范围限制,所以当你精度值越大时,越不精确了。取了例子,众所周知单精度浮点型的有效数字长度为7位(不知道的小朋友要好好复习C语言了),那么比如一个数字2.1234567891*10^14,那么赋给float后他就变成了2.1234567*10^14,后面都是精确的了,那么这个数字的无效范围就变成了21345670000000---2134567999999999,可见其多么不精确了。 那么IQmath是不是可以用同样的方法理解呢,答案是类似的,IQmath的IQ型不像FLOAT32分成3个部分,而是分成了2个部分,整数(符号位包括其中)位和小数位,我仔细看了下IQmath官方的手册,其实每个IQ都是个LONG型,通过不同的位数的定标(其实就是定小数点的位置),来实现不同精度的小数和取值范围,那么IQ15就是用低15位来表示小数位,用来表示整数的部分就是高(32-15)位了,那么照这个思路,我们要把一个整形Uint6直接赋给IQ15也是很容易的了,只要赋值后,再将IQ值向左移位15位就好了。经过实验发现果然是这样的。这样的话,以后IQ和整型的转换就变得非常简单了,如果你愿意的话,都可以替IQmath补充函数这类函数进去,这样对各种数据的处理会变得更加游刃有余。