算法函數代碼:
1 int bit_count_one(unsigned int n) 2 { 3 n=(n&0X55555555)+((n>>1)&0x55555555); 4 printf("%d\n",n); 5 6 n=(n&0X33333333)+((n>>2)&0x33333333); 7 printf("%d\n",n); 8 9 n=(n&0X0f0f0f0f)+((n>>4)&0x0f0f0f0f); 10 printf("%d\n",n); 11 12 n=(n&0X00ff00ff)+((n>>8)&0x00ff00ff); 13 printf("%d\n",n); 14 15 n=(n&0X0000ffff)+((n>>16)&0x0000ffff); 16 printf("%d\n",n); 17 18 return n; 19 }
下面我們來詳細解說如下代碼:
0X55555555的二進制位01010101010101010101.......
n&0X55555555意思就是保留0,2,4,6,8.....等偶數位上的1,而(n>>1)&0X55555555是代表保留奇數位上的1,然后兩者相加,相加的意思是將相鄰的二進制相加,又因為二進制最大為1,1+1=10,用兩個字節來存儲且不會溢出
0X33333333的二進制為0011001100110011.........
與上意思相同,不過是以兩個字節為單位,相鄰的兩個二進制位相加(左兩個,有兩個)
正好對應(n>>2)
0X0f0f0f0f的二進制為000011110000111100001111.......
總的來說:
1.用相鄰的1位相加
2.用相鄰的2位相加
3.用相鄰的4位相加
4.用相鄰的8位相加
5.用相鄰的16位相加
實例:用上圖二進制來做1101 1001
第一步,相鄰的1位相加 (兩個bit存儲)
1+1=10 0+1=01 1+0=01 0+1=01
所以n=1001 0101
第二步,相鄰的2位相加 (四個bit存儲)
10+01=0011 01+01=0010
所以n=0011 0010
第三步,相鄰的4位相加 (八個bit存儲)
0011+0010=0000 0101 由於樣例為1個字節所以只有相鄰的4的字節相加,當為int型時,則是相鄰的16個字節相加