该算法的第一部分是乘以7的倒数的近似值。在这种情况下,我们正在近似地计算带有整数乘法和右移的倒数。
首先,我们将值-1840700269
(八进制-015555555555
)视为32位整数。如果将其读取为无符号的32位整数,则其值为2454267027
(octal22222222223
)。事实证明,2454267027 / 2^34
它非常接近1/7
。
为什么我们选择这个数字和2的这个特殊幂?我们使用的整数越大,近似值越接近。在这种情况下,2454267027
似乎是最大的整数(满足上述属性),您可以用该整数乘以带符号的32位int而不溢出64位int。
接下来,如果我们立即右移>> 34
并将结果存储在32位int中,我们将失去两个最低位的精度。这些位对于确定整数除法的正确底限是必需的。
我不确定第二行是否已从x86代码正确翻译。在这一点上,temp
大约是num * 4/7
,因此num * 4/7 + num
,移位会给您大约num * 1/7 + num * 1/4
很大的误差。
例如,将输入作为57,其中57 // 7 = 8
。我也在代码中验证了以下内容:
无论如何,对于最后一行,这是我们在以这种方式计算有符号整数除法之后进行的调整。我引用了骇客对签名划分的高兴部分:
该代码最自然地计算下限分割结果,因此我们需要进行更正以使其计算常规的截断为0的结果。如果被除数为负,则可以通过将三个计算指令加到被除数上来完成此操作。
在这种情况下(请-1
参阅您的其他帖子),您似乎正在执行带符号的班次,因此在负数的情况下它将减去。给出的结果+1
。
这甚至不是您能做的。这是一个甚至更疯狂的博客文章,内容涉及如何只用一个乘法就将其除以7。