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 n3n=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。