2

我们正在使用以下算法进行一些 32 位 * 32 位乘法运算

让我们想将 a(32 位)与 b(32 位)相乘,两者都有符号,

a = ah * 2^16 + al [ah - 高 16 位,al - 低 16 位]

b = bh * 2^16 + bl [bh - 高 16 位,bl - 低 16 位]

我们正在有效地做

结果 = (al * bl) + (((ah * bl) + (al * bh)) * 2^16) + ((ah * bh) * 2 ^ 32) ~~~


我的问题,

他们有更好的方法吗?

4

4 回答 4

7

在任何主流编译器中,在 32 位平台上模拟 64 位整数将与您自己进行多步数学运算一样有效。但它会更可靠地正确。

当使用大到足以溢出的值进行简单的算术运算时,即使是我见过的最优化的数学库也只使用 int64。

于 2009-08-31T19:15:35.293 回答
4

谷歌“Karatsuba 乘法”。

哦,在您的代码中,将常量 2​​^15(它出现两次)更改为 2^16。

于 2009-09-04T07:24:55.627 回答
3

答案是否定的,除了使用位移和掩码代替 2^n 之外,没有更好的处理方式。即:

a * 2^n <=> a << n

其次,您的整数是签名的还是未签名的?如果他们签署了,那就改变了。

第三,我不确定您的 2^15 是否正确。如果它至少是无符号的,则您希望将位移动 16 而不是 15。

最后,您必须注意低位 int 中的整数溢出。如果将溢出的低位 int 中的数字相加,则需要正确增加高位 int 的容量。

于 2009-08-31T01:59:34.590 回答
1

您需要知道(指定)如何存储 64 位值 - 大概是一对 32 位值,可能是数组的两个元素,或结构的两个元素。您还需要考虑如何将标志信息存储在结果中。

机械地,您可能希望将两个有符号值都转换为无符号值,然后按照您显示的线进行拆分和重新组装,注意确保低位 32 位值的进位在高位 32 位中得到正确管理价值。

根据您最初的设计决定,您可能还需要调整结果符号的表示,甚至可能需要调整所有其他位。

类似的评论适用于将两个 16 位数字相乘而没有任何 32 位结果,这曾经很重要,但大多数人不必担心。

于 2009-08-31T02:15:14.240 回答