定点缩放和乘法精度

时间:2013-09-27 17:24:58

标签: c precision fixed-point

我需要对定点变量x(带有二进制点6 [BP6]的无符号16位整数[U16]类型)执行乘法运算,其系数为A,我知道将始终在0和1之间。代码用C语言编写,用于32位嵌入式平台。

我知道如果我也将这个系数设为U16 BP6,那么我最终会得到乘法中的U32 BP12。我想将这个结果重新缩放到U16 BP6,所以我只是丢掉了前10位和后6位。

然而,由于系数在精度上受到小数位数的限制,并且我不一定需要整数10位整数,我以为我可以将系数变量A设为U16 BP15可以产生更精确的结果。

我已经制定了以下示例(请耐心等待):

假设x = 172.0(十进制),我想使用系数A = 0.82(十进制)。理想的十进制结果为172.0 * 0.82 = 141.04。

二进制,x = 0010101100.000000

如果我将BP6用于A,则二进制表示将是

    A_1 = 0000000000.110100 = 0.8125 or
    A_2 = 0000000000.110101 = 0.828125

(取决于价值是基于楼层还是上限)。

在x和A的任一值之间执行二进制乘法得出(省略前导零):

    A_1 * x = 10001011.110000000000 = 139.75 
    A_2 * x = 10001110.011100000000 = 142.4375

在这两种情况下,调低最后6位都不会影响结果。

现在,如果我将A扩展为BP15,那么

    A_3 = 0.110100011110110 = 0.82000732421875

和由此产生的乘法产生

    A_3 * x = 10001101.000010101001000000000 = 141.041259765625

当修剪额外的15个小数位时,结果为

    A_3 * x = 10001101.000010 = 141.03125

所以在这里很清楚,通过扩展系数以获得更多的小数位会产生更精确的结果(至少在我的例子中)。这一般会成立吗?在实践中使用这个好/坏吗?我错过了什么或误解了什么?

编辑:我应该在这里说“准确性”代替“精确度”。我正在寻找一个更接近我期望值的结果,而不是包含更多小数位的结果。

1 个答案:

答案 0 :(得分:1)

完成类似的代码后,我会告诉你,你正在做的事情总体上会与以下问题保持一致。

  1. 在二进制点转换时,很容易出现意外溢出。建议进行严格的测试/分析和/或代码检测。 Notable failure: Ariane_5

  2. 你想要精确,因此我不同意“砍掉......最后6”。相反,我建议在处理时间允许的情况下舍入结果。使用MSBit可能会调整结果。