查看由编译器生成的x86程序集,我注意到(无符号)整数除法有时实现为整数乘法。这些优化似乎遵循形式使用乘法执行整数除法
value/n => (value * ((0xFFFFFFFF/n) + 1))/0x100000000
例如,通过9执行除法:
12345678/9 = (12345678 * 0x1C71C71D)/0x100000000
由3所述的分割将利用乘法0x55555555 + 1
,等等。
利用mul
指令将结果的高位部分存储在edx
寄存器中的事实,最终的除法结果可以使用带有魔值的单乘法获得。 (虽然这种优化有时与最后按位移位结合使用)。
我想了解一下这个实际工作原理。这种方法何时有效?为什么必须将1添加到我们的“幻数”中?
您乘以的常数是倒数的近似值。随机的+/- 1在这里和那里确保它总是正确地“圆化”。证明一种特定的方法是正确的,可以通过数学方法或通过对所有分子进行强力测试来完成。 (对于32位,这是完全可行的。) – Mysticial
@Mysticial:这看起来像是对我的回答。 –
@ScottHunter也许以后当我不工作时。我没有很多工具可以给出全面的答案。 – Mysticial