来源我的答案:
我在这里有点不擅长,我试图了解这种特殊优化是如何工作的。
如答案中所述,gcc 会将整数除以 7 优化为:
mov edx, -1840700269
mov eax, edi
imul edx
lea eax, [rdx+rdi]
sar eax, 2
sar edi, 31
sub eax, edi
将其转换回 C 为:
int32_t divideBySeven(int32_t num) {
int32_t temp = ((int64_t)num * -015555555555) >> 32;
temp = (temp + num) >> 2;
return (temp - (num >> 31));
}
我们来看看第一部分:
int32_t temp = ((int64_t)num * -015555555555) >> 32;
为什么是这个数字?
好吧,让我们把 2^64 除以 7,看看会出现什么。
2^64 / 7 = 2635249153387078802.28571428571428571429
看起来很乱,如果我们把它转换成八进制呢?
0222222222222222222222.22222222222222222222222
这是一个非常重复的模式,这肯定不是巧合。我的意思是我们记得 7 是0b111
,而且我们知道当我们除以 99 时,我们往往会得到以 10 为底的重复模式。因此,当我们除以 7 时,我们会在以 8 为基数的重复模式是有道理的。
那么我们的号码是从哪里来的呢?
(int32_t)-1840700269
是相同的(uint_32t)2454267027
* 7 = 17179869189
最后 17179869184 是2^34
这意味着 17179869189 是 7 2^34 的最接近的倍数。或者换句话说,2454267027 是适合的最大数字,uint32_t
当乘以 7 时,它非常接近 2 的幂
这个八进制数是多少?
0222222222223
为什么这很重要?好吧,我们想除以 7。这个数字是 2^34/7... 大约。因此,如果我们乘以它,然后左移 34 次,我们应该得到一个非常接近确切数字的数字。
最后两行看起来像是为了修补近似误差而设计的。
也许在这个领域有更多知识和/或专业知识的人可以加入这一点。
>>> magic = 2454267027
>>> def div7(a):
... if (int(magic * a >> 34) != a // 7):
... return 0
... return 1
...
>>> for a in xrange(2**31, 2**32):
... if (not div7(a)):
... print "%s fails" % a
...
故障从 3435973841 开始,有趣的是 0b11001100110011001100110011010001
对逼近失败的原因进行分类有点超出我的理解,以及补丁修复它的原因也是如此。有谁知道除了我在这里放下的魔法之外,魔法是如何运作的吗?