嗨,我正在尝试分析功能
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的数量。但是在那之后我迷路了。个别地,我知道代码在做什么,但是我不知道为什么这样做,以及背后的想法是什么。
答案 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
可以一次将它们全部加在一起。