【问题标题】:Fixed Point Multiplication of Unsigned numbers无符号数的定点乘法
【发布时间】:2013-01-23 20:40:33
【问题描述】:

我正在尝试用定点数解决乘法问题。数字是 32 位的。我的架构是 8 位的。所以这里是:

  1. 我使用 8.8 表示法,即 8 表示整数,8 表示分数。

  2. 我有 A78,即 10.468。我取它的二进制补码,答案是 FFFFF588,我将它截断为 16 位作为 F588 并存储它。原因是,我只想将两个 2 字节的数字相乘。

  3. 现在,当我将此 F588(负 10.42 或 0x0A78)乘以 0xFF4B(即 0x00B5(0.707)的二进制补码)时,答案应该是 0x0766。或者类似的东西。

另一方面,我得到的是 66D8。

现在有趣的地方是:如果我将 B5 的负数存储在 32 位的二进制补码中,我得到 0xFF5266D8,我将其右移 8 位,然后截断为 16 位,答案是 0x5266。

另一方面,如果我将负数 10.42 存储在 32 位中,我得到 0xF58F66D8,在移位 8 位并截断后变为 8F66。

但是,如果我将这两个数字都存储为 32 位格式,那么只有在移位和截断后我才能得到正确的结果,即 0x0766。

为什么会这样?我知道当我们从 32 位到 16 位时,信息丢失是固有的,但是 0x07 与 0x55 有很大不同。我将非常感谢您的回复。

【问题讨论】:

    标签: c numbers fixed-point


    【解决方案1】:

    让我们只看整数表示。您有两个 16 位整数,xy,并形成它们的 16 位二进制补码。但是,您将这些 16 位补码保存在 32 位对象中。在 32 位中,您拥有的是 65536–x 和 65536–y。 (例如,您从 0xa78 开始,将其补充为 0xfffff588,并丢弃位以获得 0xf588。等于 0x10000-0xa78。)

    当您将这些相乘时,结果为 65536•65536 – 65536•x – 65536•y + xy .

    65536•65536 是 232,因此它消失了,因为无符号 32 位算术是以 232 为模执行的。你剩下 – 65536•x – 65536•y + xy

    现在你可以看到问题了:xy 是两个 16 位值的乘积,所以它流入了 32 位的高 16 位。在上面,你还有 - 65536•x - 65536•y,这是你不想要的。

    一个简单的方法是通过乘法来保留补码的所有 32 位。例如,当你取 0xa78 的二进制补码时,你得到 0xfffff588。然后你丢弃了高位,只保留 0xf588。如果你不这样做,你会将 0xfffff588 乘以 0xffffff4b,乘积将是 0x766d8,当移动分数时,将是 0x766,这就是你想要的结果。

    如果由于将二进制补码存储到 16 位对象中而丢失了高位,则只需在重新加载对象时通过扩展符号位来恢复它们。也就是说,取第 15 位并在第 16 位到第 31 位重复。一个简单的方法是将 16 位对象加载到 16 位有符号整数,然后将 16 位有符号整数转换为无符号 32-位整数。

    【讨论】:

    • 请注意,OP 在移位后将结果截断为 16 位,因此它们只需要结果的高 16 位的低 8 位 - 这意味着它们可以在 24 位中进行乘法而不是大于 32(而且由于它是在 8 位架构上实现的,那肯定是一个胜利)。
    猜你喜欢
    • 2019-11-12
    • 1970-01-01
    • 1970-01-01
    • 2013-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多