以乘代除之魔法数原理

以除 3 为例:

除 3 即乘 1 / 3。

对于有符号数,先乘 2 / 3,将 2 / 3 左移 31 位,留最高位表示符号位,为 55555556h(魔法数)。与原数 imul,则直接取 edx 即为答案。

为何要乘 2 / 3 直接得答案呢?

先查对于无符号数,乘 2 / 3,将 2 / 3 左移 32 位,为 0AAAAAAABh。与原数 mul 之后,需要右移 32 位回,但由于汇编乘法规则,直接取用 edx 即可。由于乘 2 / 3,则将 edx 右移 1 位才是结果。

对于有符号数来说,由于需要右移 31 位,并再右移 1 位以抵消 2 / 3 成为 1 / 3,而直接取用 edx 刚好完成了右移 32 位(也就是说 eax 的 32 位是没用的)。这也即为何除 3 要乘 2 / 3 的原因。

通过左移右移的操作,使得除整数变为乘小数,左移之成为乘整数(近似值),从而达到优化计算的目的。
除 3 的魔法数计算:2 / 3 => ( 2 << 32 ) / 3 => 0AAAAAAABh

你可能感兴趣的:(以乘代除之魔法数原理)