无符号数的定点乘法

5
我正在尝试使用定点数解决乘法问题。这些数字是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相差很大。如果您能回答我的问题,我将不胜感激。

1个回答

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执行的。所以你只剩下-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位整数。

请注意,OP在移位后将结果截断为16位,因此他们只需要结果的上16位的低8位 - 这意味着他们可以在24位中进行乘法而不是32位(并且由于它是在8位架构上实现的,这肯定是一个胜利)。 - caf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接