无符号数的不动点乘法

时间:2013-01-23 20:40:34

标签: c numbers fixed-point

我正在尝试用定点数解决乘法问题。数字是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。或类似的东西。

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

    现在这里有趣的地方:如果我将B5的负数存储在32位的两个恭维中,我得到0xFF5266D8,我向右移8位,截断到16位,答案是0x5266。

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

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

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

1 个答案:

答案 0 :(得分:4)

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

乘以这些值时,结果为65536•65536 - 65536• x - 65536• y + x y

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

现在您可以看到问题: x y 是两个16位值的乘积,因此它会流入32位的高16位。在那里,你仍然有 - 65536• x - 65536• y ,你不需要。

一种简单的方法是乘法以保留补码的所有32位。例如,当你使用0xa78的两个补码时,你得到了0xfffff588。然后你丢弃了高位,只保留0xf588。如果你不这样做,你会将0xfffff588乘以0xffffff4b,产品将是0x766d8,当移动分数时,它将是0x766,这是你想要的结果。

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