1

我需要对具有系数的定点变量x(无符号 16 位整数 [U16] 类型,二进制点 6 [BP6])执行乘法运算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.

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

    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

所以这里很清楚,通过扩展系数以获得更多小数位会产生更精确的结果(至少在我的示例中)。这是否普遍适用?这在实践中使用是好还是坏?我是否遗漏或误解了什么?

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

4

1 回答 1

1

完成了类似的代码后,我会说你所做的将在以下问题上普遍适用。

  1. 围绕二进制点移动时很容易出现意外溢出。建议进行严格的测试/分析和/或代码检测。 显着失败:Ariane_5

  2. 您想要精确,因此我不同意“关闭...最后 6 个”。相反,我建议在处理时间允许的情况下四舍五入您的结果。使用被截断的 MSBit 来调整结果。

于 2013-09-27T17:57:05.380 回答