您的位置:首页 > 其它

Count the number of 1(MIT hackmem)

2010-09-02 15:36 477 查看
MIT Hackmem

int bitcount(unsigned int n)
{
/* works for 32-bit numbers only */
/* fix last line for 64-bit numbers */
register unsigned int tmp;
tmp = n - ((n >> 1) & 033333333333) - ((n >> 2) & 011111111111);
return ((tmp + (tmp >> 3)) & 030707070707) % 63;
}

首先,可以把 n 看成是8进制的数,即把 n 三位三位的分开,每位是一个bit。
一个三bit的数字可以看成是abc,它的和为4a+2b+c。如果我们将这个数右移一位,即得到ab,其和为2a+b。将原来的n减去右移一位后的n,得到和为2a+b+c。如果我们在把n右移一位,即把原来的n 右移两位的话,我们将得到一个a,然后再用前面减法的结果2a+b+c减去右移两位后的n 的话,得到和为a+b+c,如下面所示:

a b c n1
右移一位 a b n2
再右移一位 a n3
n=n1;
n'=n1-n2;
n''=n'-n3
=n1-n2-n3
=4a+2b+c -(2a+b) -a
=a+b+c;
tmp = n - ((n >> 1) & 033333333333) - ((n >> 2) & 011111111111);

即将每三位的和加到末尾上,其余位为0。

然后,程序return了一个值。

return ((tmp + (tmp >> 3)) & 030707070707) % 63;

这里它是将tmp看成是有六bit数组成的32位数,当然这个是从最低有效位算起的,将每六位数的和加到末尾上,然后用63求余(这里用63求余,是因为1000000是64,如果将tmp看成是由六bit数组成的话,高于63就有一个1,所以可以用取余的方法),最后得到共含有的1的个数。

对于64-bit的数而言,我们可以用3倍的八进制数(即3bit位),即1023。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: