定点的四则运算以及定点精度损失的影响

优质
小牛编辑
137浏览
2023-12-01

定点的四则运算

定点加法

原则:统一定标到同一个合适定标值

举例:x = 16384; y = 25395; x 的定标是Q15,y 的定标是 Q13。计算 z = x + y,要求将输出 z 的定标设定为 Q12。
y = y<<2 = 101580 // y的定标由 Q13 提升到 Q15
z = x + y = 16384 + 101580 = 117964 // Q15
z = (int) (z>>3) = (int)(117964>>3) = 14745 // Q12
z定点前的值:float(z)/(1<<12) = 3.5598

定点减法

原则:统一定标到同一个合适定标值

举例:x = 16384; y = 25395; x 的定标是Q15,y 的定标是 Q13。计算 z = x - y,要求将输出 z 的定标设定为 Q12。
y = y<<2 = 101580 // y的定标由 Q13 提升到 Q15
z = x - y = 16384 - 101580 = -85196 // Q15
z = (int) (z>>3) = (int)(-85196>>3) = -10649.5 // Q12
z定点前的值:float(z)/(1<<12) = -2.5999

定点乘法

原则:不要发生数据溢出

举例:x = 16384; y = 25395; x 的定标是Q15,y 的定标是 Q13。计算 z = x * y,要求将输出 z 的定标设定为 Q12。
如果两个定点数相乘,那么相乘得到的值的定标等于两个乘数的定标值和,这个不难理解。
z = x * y = 16384 * 25395 = 416071680 // Q15 + Q13 = Q28
z = (int) (z>>16) = (int)(416071680>>16) = 6348 // Q28 - 16 = Q12
z定点前的值:float(z)/(1<<12) = 1.5499

定点除法

原则:不要发生数据溢出

举例:x = 16384; y = 25395; x 的定标是Q15,y 的定标是 Q13。计算 z = x / y,要求将输出 z 的定标设定为 Q12。
如果两个定点数相除,那么相乘得到的值的定标等于两个乘数的定标值差,这个不难理解。为了提升精度,一般将被除数精度提到最高,本题的 x 由 Q15 提升到了 Q27。
x = x<<12 = 67108864 // Q15+Q12 = Q27
z = x / y = 67108864 / 25395 = 2642 // Q27 - Q13 = Q14
z = (int) (z>>2) = (int)(416071680>>2) = 660 // Q12
z定点前的值:float(z)/(1<<12) = 0.16113

分析定点精度损失的影响

这里只提供思路,具体要依据算法的需求来定。 就拿上面的一加法例子。Q15 的 x = 16384 实际上是 0.5,没有精度损失,Q13 的 y = 25395 实际上是 3.0999(原意想表达 3.1,Q13 只能表达 3.0999,误差 0.0001)。由于 y 是 Q13,如果要计算 z = x+y,其结果 z 取 Q15 或 Q13, Z 值误差是最小的,因为运算过程中不会产生精度损失。但是如果采用 Q12 的结果就会产生 1bit 精度损失,故而得到的值 z = 3.5598 比真实的 x+y=3.5999,误差达到 0.0401,至于这个误差对算法的影响,就要从算法本身来考量了。