Java中的Integer.bitCount(i)的返回值是i的二進制表示中1的個數。源碼如下:
public static int bitCount(int i) { // HD, Figure 5-2 i = i - ((i >>> 1) & 0x55555555); i = (i & 0x33333333) + ((i >>> 2) & 0x33333333); i = (i + (i >>> 4)) & 0x0f0f0f0f; i = i + (i >>> 8); i = i + (i >>> 16); return i & 0x3f; }
源碼解析如下:
public static int bitCount(int i) { // HD, Figure 5-2 /** * 每兩位為一個單元,把原來單元中1的個數儲存在原來的單元中 */ i = i - ((i >>> 1) & 0x55555555); /** *0x33333333其實就是二進制……00110011(共32位),因為上面的每兩位代表1的個數,所以下面的這幾行就是要把上面每兩位 * 的數字加起來,下面的這行代碼可以這樣理解,每4位分為一組,然后4位中的每兩位相加,相加的結果在儲存到這4位二進制數中, * i & 0x33333333表示每4位中的低2位,(i >>> 2) & 0x33333333表示每4位中的高2位,然后在相加 */ i = (i & 0x33333333) + ((i >>> 2) & 0x33333333); /** * 這個更好理解,i >>> 4表示往右移動了4位,然后在與i相加,相當於每8位一組,然后8位中的高4位與低4位相加儲存在低4位中, * 然后這里在與0x0f0f0f0f進行與運算,把高4位完全置為0了,因為0x0f0f0f0f用二進制表示就是00001111000011110000111100001111, * 看到這里可能有些困惑,這里為什么要與0x0f0f0f0f進行與運算,因為每8位一組的話,最多也就是8,那么4位數足夠了,高4位就沒有必要了, * 如果不置為0有沒有影響,其實如果1的位數極少的話是沒什么影響的,但如果1的位數比較多到后面計算的結果可能就會往前進位,導致結果錯誤, * 所以這一步要進行一次與運算,那為什么上面的那行代碼沒有把4位一組中的高兩位置0,這是因為4位一組最多有4個1,而2位二進制數最多表示3, * 小於4,所以不能置為0, * */ i = (i + (i >>> 4)) & 0x0f0f0f0f; /** * 和上面類似,每16位分為一組,每組中的高8位和低8位相加,這里的代碼相加的很干凈,因為無論是高8位還是低8位中的前4位在上面一行中 * 都已經置為0了,這里也可以像上面那樣,加完之后在與0x00ff00ff進行與運算,但其實這里已經沒有必要了,因為int類型為32位, * 最多也就32個1,用8位數儲存足夠了,所以不會超過8位,也就不用擔心超過8位在往前進1位的問題了。 */ i = i + (i >>> 8); /** * 和上面類似,就不在詳述 */ i = i + (i >>> 16); /** * 到最后為什么要和0x3f進行與運算,0x3f用二進制表示就是111111,因為上面兩行沒有進行與運算,所以前面的數據都是無效的, * 只有最后8位是有效的,而后8位的前兩位不用說肯定為0,因為最多也就32個1,用后面6位數表示就已經足夠了,所以這里與0x3f * 進行與運算,來計算出最終1的個數 */ return i & 0x3f; }
i=031bi