BITCOUNT宏所需的说明

时间:2010-01-05 22:31:04

标签: c++ c macros

有人可以解释一下这是如何工作的吗?

#define  BX_(x)         ((x) - (((x)>>1)&0x77777777)                    \
                             - (((x)>>2)&0x33333333)                    \
                             - (((x)>>3)&0x11111111))


#define BITCOUNT(x)     (((BX_(x)+(BX_(x)>>4)) & 0x0F0F0F0F) % 255)

澄清:

理想情况下,答案将从以下几点开始:

宏:“BX_”从传入的数字中减去三个值。

这三个值代表:

  1. XXXXX
  2. YYYYY
  3. ZZZZZ
  4. 这允许BITCOUNT()按如下方式工作......

    干杯,

    大卫

2 个答案:

答案 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