设置位计数

时间:2018-10-12 23:07:02

标签: algorithm bit-manipulation

嗨,我正在尝试分析功能

int countBit(uint32_t n) {
    n = (n & 0x55555555) + ((n & 0xAAAAAAAA) >> 1);
    n = (n & 0xC30C30C3) + ((n & 0x0C30C30C) >> 2) + ((n & 0x30C30C30) >> 4);
    return n % 63;
}

现在我已经弄清楚了它是对设置位的数量进行计数的(最初,函数名有所不同,因此并不明显。)

我也知道那行

n = (n & 0x55555555) + ((n & 0xAAAAAAAA) >> 1);

在随后的对中给出1的数量。但是在那之后我迷路了。个别地,我知道代码在做什么,但是我不知道为什么这样做,以及背后的想法是什么。

1 个答案:

答案 0 :(得分:2)

哦,我以前没看过这个。这非常聪明,尽管我想知道模数与更多比特旋转相比有多快。

无论如何,在n = (n & 0x55555555) + ((n & 0xAAAAAAAA) >> 1)之后,我们有16个2位计数。

(n & 0xC30C30C3)分离出6个计数,这些计数以6位的倍数移位,即乘以64的倍数。由于64%63 = 1,因此使用模数模数63会将所有这些计数加在一起。 + ((n & 0x0C30C30C) >> 2)隔离移位6k + 2位的计数,并将其添加到上面。 + ((n & 0x30C30C30) >> 4)对移位6k + 4位的计数执行相同的操作。这些添加之后,我们有6个5位计数器,%63可以一次将它们全部加在一起。