平行算法
int BitCount(unsigned int n)
{
n = (n &0x55555555) + ((n >>1) &0x55555555) ;
n = (n &0x33333333) + ((n >>2) &0x33333333) ;
n = (n &0x0f0f0f0f) + ((n >>4) &0x0f0f0f0f) ;
n = (n &0x00ff00ff) + ((n >>8) &0x00ff00ff) ;
n = (n &0x0000ffff) + ((n >>16) &0x0000ffff) ;
return n ;
}
先说n &0x55555555,操作如下:
与结果abcdefgh010101010b0d0f0hhijklmno010101010i0k0m0opqrstuvw010101010q0s0u0wxyzabcde010101010y0a0c0e
再说(n >>1) &0x55555555,操作如下:
与结果0abcdefg010101010a0c0e0ghhijklmn010101010h0j0l0nopqrstuv010101010p0r0t0vwxyzabcd010101010x0z0b0d
于是乎,n = (n &0x55555555) + ((n >>1) &0x55555555)应该是:
+结果0b0d0f0h0a0c0e0g相0i0k0m0o0h0j0l0n邻0q0s0u0w0p0r0t0v相0y0a0c0e0x0z0b0d加
可知上述这一行代码实际是实现了相邻的两个二进制二相加,后面代码一次是相邻2位、4位、8位···二进制位相加,实现了二进制数中对1的个数的统计功能。以217(11011001)为例,有图有真相,下面的图足以说明一切了。217的二进制表示中有5个1

总结:运用了分治法计算二进制数中1的个数,
(n & 0x55555555) + ((n >> 1) & 0x55555555) 计算每对相邻的2位中有几个1
(n & 0x33333333) + ((n >> 2) & 0x33333333) 计算每相邻的4位中有几个1
接下来8位,16位,32位,对于32位的机器,5条位运算语句就够了。
快速法
int BitCount(unsigned int n)
{
unsigned int c =0 ;
for (c =0; n; ++c)
{
n &= (n -1) ; // 清除最低位的1
}
return c ;
}
更多方法参见【这里】