我们使用以下算法相乘两个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)~~~
我的问题,
他们是否有更好的方法来做到这一点?
我们使用以下算法相乘两个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)~~~
我的问题,
他们是否有更好的方法来做到这一点?
在任何主流编译器中,在32位平台上模拟64位整数将与自己完成多步数学一样高效。但它会更可靠地正确。
在做足够大的溢出数值的简单算术时,即使是我见过的最高度调整的数学库也只是使用int64。
答案是否定的,除了使用位移和掩码而不是2^n之外没有更好的方法来做事。即:
a * 2^n <=> a << n
其次,你的整数是有符号还是无符号?如果他们签了字,那就改变了事情。
第三,我不确定你的2^15是否正确。如果它至少没有符号,则要将位移位16而不是15.
最后,您必须注意低位int中的整数溢出。如果将低位整数中的数字加在一起,那么溢出它的容量就需要正确地增加高位int。
+1我猜2^15是一个错误。可悲的是,这是最好的方法~~~ – Alphaneo 2009-08-31 07:06:56
您需要知道(指定)64位值的存储方式 - 大概是一对32位值,可能是数组的两个元素或结构的两个元素。您还需要考虑标记信息将如何存储在结果中。
从机械上讲,您可能希望将两个有符号值转换为无符号值,然后沿着显示的行进行拆分和重新组合,注意确保从低位32位值的进位在高位订购32位值。
根据您的初始设计决定,您可能还需要对结果符号的表示形式进行微调,甚至可能需要对所有其他位进行微调。
相似的评论适用于将两个16位数字相乘而没有任何32位结果,这是曾经很重要,但大多数人不必担心。
谷歌“Karatsuba乘法”。
OIh,并在您的代码中,将常量2^15(它出现两次)更改为2^16。
在什么处理器上?在x86上,例如,当您多个两个32位数字时,结果的高32位存储在EDX中,而低位位于EAX中。类似于16位。 – David 2009-08-31 02:48:29
我们需要设计这是一个32位处理器,并且处理器可以是任何类似于ARM,MIPS或基于客户的东西...... – Alphaneo 2009-08-31 03:17:17
使用int64_t并让编译器代码生成器担心如何实现它。如果Codegen很差,您只需要手动执行某些操作,这对于这种简单的情况不太可能。 – 2009-11-17 22:14:59