今天在做深入理解计算机系统的LAB1,其中有道题求二进制数中的1的个数
看到这种算法
int bitCount(int x)
{
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= (1101)( 1001)( 1111)( 1000)( 0001) ...
与上0x55555555,就是取了每个括号的的第二位和第四位,然后((n >>1) &0x55555555)其实就是取了每个括号里的第一位和第三位,相加就实现了将每个括号里的第一位加上第二位,第三位加上第四位,以此类推得到(10)(01)(01)(01)(10)(10)(01)(00)(00)(01)...每两位就代表
(1101)(1001)(1111)( 1000)( 0001) 中各个括号中的两位里面的1的个数。接下来与上(n &0x33333333) + ((n >>2) &0x33333333),
大致过程如下:
(10)(01)(01)(01)(10)(10)(01)(00)(00)(01).
00 11 00 11 00 11 00 11 即&0x33333333
(10)(01)(01)(01)(10)(10)(01)(00)(00).
00 11 00 11 00 11 00 11 即&0x33333333
这样相加又会将高的二位与低的二位相加得到表达式n中四个位里面1的个数。0x55555555和0x33333333这些主要是为了取出一块数据。