https://blog.csdn.net/baidu_24281959/article/details/52015811 Original Source: http://www.cnblogs.com/s_agapo/archive/2012/03/20/2407332.html http://blog.csdn.net/sonictl/article/details/9018681 原文基于信号处理,本文对原文进行了精简和勘误,主要就浮点转定点运算的思想及实现进行说明: 1. 简介: 采用定点数进行数值运算,其操作数一般采用整型数来表示。 一个整型数的最大表示范围取决于运算芯片所给定的字长,一般为16位或24位。 显然,字长越长,所能表示的数的范围越大,精度也越高。如无特别说明,本文均以16位字长为例。 参与运算的数以二进制补码形式表示。每个16位数用一个符号位来表示数的正负,0表示数值为正,1则表示数值为负。 其余15位表示数值的大小。 1.1 示例: 1.2 定点表示 参与数值运算的数为16位的整型数。但在许多情况下,数学运算过程中的数不一定都是整数。 应该说,运算芯片本身无法处理小数。关键就是由程序员来确定一个数的小数点处于16位中的哪一位。这就是数的定标。 {通过设定小数点在16位数中的不同位置,就可以表示不同大小和不同精度的小数} 数的定标有Q表示法和S表示法两种。下面列出了一个16位数的16种Q表示、S表示及它们所能表示的十进制数值范围: Q表示 S表示 十进制数表示范围 Q15 S0.15 -1≤x≤0.9999695 1.3 定点表示示例: 同样一个16位数,若小数点设定的位置不同,它所表示的数也不同(首位为符号位): 16进制数2000 H= 二进制数0
010 0000 0000 0000 B= 十进制数8192, Q0表示法 2. 浮点定点转换: 不同的Q所表示的数不仅范围不同,而且精度也不相同。 Q越大,数值范围越小,但精度越高;相反,Q越小,数值范围越大,但精度就越低。 E.g. Q0 的数值范围是-32768到+32767,其精度为1;而Q15的数值范围为-1到0.9999695,精度为1/32768=0.00003051。 因此,对定点数而言,数值范围与精度是一对矛盾。 一个变量要想能够表示比较大的数值范围,必须以牺牲精度为代价;而想精度提高,则数的表示范围就相应地减小。 在实际的定点算法中,为了达到最佳的性能,必须充分考虑到这一点。 2.2 转换关系: 浮点数与定点数的转换关系可表示为: 浮点数(Fx)转换为定点数(Ix):Ix = (int)x* 2^Q 2.3 转换示例: 浮点数 Fx = 0.5,定标 Q = 15,则定点数: Ix = floor(0.5*32768) = 16384 反之,一个用 Q = 15 表示的定点数Ix = 16384,其浮点数为: Fx = 16384 * 2^(-15) = 16384 / 32768 = 0.5 浮点数转换为定点数时,为了降低截尾误差,可以在取整前可以先加上0.5,视情况而定。 3. C语言实现定点预算模拟: 将浮点加法/减法转化为定点加法/减法时最重要的一点就是必须保证两个操作数的定标: 若两者不一样,则在做加法/减法运算前先进行小数点的调整。 为保证运算精度,需使Q值小的数调整为与另一个数的Q值一样大。 此外,在做加法/减法运算时,必须注意结果可能会超过16位表示。 如果加法/减法的结果超出16位的表示范围,则必须保留32位结果,以保证运算的精度,否则可能会出现严重的精度丢失。 3.1 结果不超过16位的定点加法描述:
E.g.
More Examples.Here.3.2 定点乘法:
E.g.
3.3 混合表示法: 许多情况下,运算过程中为了既满足数值的动态范围又保证一定的精度,就必须采用Q0与Q15之间的表示法。 比如,数值1.2345,显然Q15无法表示,而若用Q0表示,则最接近它的数是1,精度无法保证。因此,数1.2345最佳的表示法是Q14。 例如,程序员了解到上述乘积不会大于1.9999390,就可以用Q14数表示乘积,而不是理论上的最佳情况Q13。 |
|