2009-08-31 95 views
2

我们使用以下算法相乘两个32位的数字,而不使用64位的int

我们,我们要乘以(32位)与B(32位)做了一些32位* 32位乘法,双方签字,

一个=啊* 2^16 +人[啊 - 高16位,人 - 低16位]

b = BH * 2^16 + BL [BH - 高16位,BL - 下16位]

我们正在有效地做

结果=(ΔL* BL)+(((啊* BL)+(ΔL* BH))* 2^16)+((*啊BH)* 2^32)~~~


我的问题,

他们是否有更好的方法来做到这一点?

+0

在什么处理器上?在x86上,例如,当您多个两个32位数字时,结果的高32位存储在EDX中,而低位位于EAX中。类似于16位。 – David 2009-08-31 02:48:29

+0

我们需要设计这是一个32位处理器,并且处理器可以是任何类似于ARM,MIPS或基于客户的东西...... – Alphaneo 2009-08-31 03:17:17

+1

使用int64_t并让编译器代码生成器担心如何实现它。如果Codegen很差,您只需要手动执行某些操作,这对于这种简单的情况不太可能。 – 2009-11-17 22:14:59

回答

7

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

在做足够大的溢出数值的简单算术时,即使是我见过的最高度调整的数学库也只是使用int64。

3

答案是否定的,除了使用位移和掩码而不是2^n之外没有更好的方法来做事。即:

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

其次,你的整数是有符号还是无符号?如果他们签了字,那就改变了事情。

第三,我不确定你的2^15是否正确。如果它至少没有符号,则要将位移位16而不是15.

最后,您必须注意低位int中的整数溢出。如果将低位整数中的数字加在一起,那么溢出它的容量就需要正确地增加高位int。

+0

+1我猜2^15是一个错误。可悲的是,这是最好的方法~~~ – Alphaneo 2009-08-31 07:06:56

1

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

从机械上讲,您可能希望将两个有符号值转换为无符号值,然后沿着显示的行进行拆分和重新组合,注意确保从低位32位值的进位在高位订购32位值。

根据您的初始设计决定,您可能还需要对结果符号的表示形式进行微调,甚至可能需要对所有其他位进行微调。

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

4

谷歌“Karatsuba乘法”。

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