有人可以解释一下这是如何工作的吗?
#define BX_(x) ((x) - (((x)>>1)&0x77777777) \
- (((x)>>2)&0x33333333) \
- (((x)>>3)&0x11111111))
#define BITCOUNT(x) (((BX_(x)+(BX_(x)>>4)) & 0x0F0F0F0F) % 255)
理想情况下,答案将从以下几点开始:
宏:“BX_”从传入的数字中减去三个值。
这三个值代表:
这允许BITCOUNT()按如下方式工作......
干杯,
大卫
答案 0 :(得分:11)
BX_(x)的输出是每个十六进制数字中的on位数。所以
BX_(0x0123457F) = 0x01121234
以下内容:
((BX_(x)+(BX_(x)>>4)) & 0x0F0F0F0F)
将计数混洗成字节:
((BX_(0x0123457F)+(BX_(0x0123457F)>>4)) & 0x0F0F0F0F) = 0x01030307
取这个结果模255加上各个字节以得到正确答案14.为了看到这个有用,只考虑一个两字节整数,256 * X + Y.这只是255 * X + X + Y和255 * X%255始终为零,所以
(256*X + Y) % 255 = (X + Y) % 255.
这扩展到四字节整数:
256 ^ 3 * V + 256 ^ 2 * W + 256 * X + Y
只需将每个256替换为(255 + 1)以查看
(256^3*V + 256^2*W + 256*X + Y) % 255 = (V + W + X + Y) % 255.
最后的观察(我用2位数的例子在地毯下扫描)是V + W + X + Y
总是小于255,所以
(V + W + X + Y) % 255 = V + W + X + Y.
答案 1 :(得分:1)
正如约翰内斯在精彩的Bit Twiddling Hacks页面中所引用的那样,对于来自AMD的Software Optimization Guide for AMD Athlon™ 64 and Opteron™ Processors页码179和180中的算法有一个非常详细的描述 - 对应于PDF的第195和196页
还描述了相同的想法和一些替代解决方案及其相对表现:this page。