最近刷题的时候看到了这样一个奇怪的函数,一开始非常不理解,后来查阅了资料,现将它记录下来。
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;
}
先说一下这个函数的功能:表示整型变量i转化成二进制表示时,1的个数。
一看很懵,不知所以然,接下来就开始解释了。
过程解释:
-
首先将整数i转换成二进制形式,如下所示:
i = b 0 ⋅ 2 0 + b 1 ⋅ 2 1 + . . . + b 30 ⋅ 2 30 + b 31 ⋅ 2 31 i=b_0\cdot2^0 + b_1\cdot2^1+...+b_{30}\cdot2^{30}+b_{31}\cdot2^{31} i=b0⋅20+b1⋅21+...+b30⋅230+b31⋅231 -
对于
i = i - ((i >>> 1) & 0x55555555);
(2的二进制位0101),得到的结果为:
i = b 0 ⋅ 2 0 + b 1 ⋅ 2 1 + . . . + b 31 ⋅ 2 31 − b 1 ⋅ 2 0 + b 3 ⋅ 2 2 + b 31 ⋅ 2 30 = ( b 0 − b 1 ) ⋅ 2 0 + . . . + b 1 ⋅ 2 1 ( b 30 − b 31 ⋅ 2 30 + b 3 1 ) = ( b 0 + b 1 ) ⋅ 2 0 + . . . + ( b 30 + b 31 ⋅ 2 30 ) i=b_0\cdot2^0+b_1\cdot2^1+...+b_{31}\cdot2^{31}-b_1\cdot2^0+b_3\cdot2^2+b_{31}\cdot2^{30}\\ =(b_0-b_1)\cdot2^0+...+b_1\cdot2^1(b_{30}-b_{31}\cdot2^{30}+b_31)\\ =(b_0+b_1)\cdot2^0+...+(b_{30}+b_{31}\cdot2^{30}) i=b0⋅20+b1⋅21+...+b31⋅231−b1⋅20+b3⋅22+b31⋅230=(b0−b1)⋅20+...+b1⋅21(b30−b31⋅230+b31)=(b0+b1)⋅20+...+(b30+b31⋅230) -
对于
i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
(3的二进制为0011)得到结果为:
i = ( ( b 0 + b 1 ) ⋅ 2 0 + ( b 4 + b 5 ) ⋅ 2 4 + . . . + ( b 28 + b 29 ⋅ 2 28 ) ) + ( ( b 2 + b 3 ) ⋅ 2 0 + ( b 6 + b 7 ) ⋅ 2 4 + . . . + ( b 30 + b 31 ) ⋅ 2 28 ) = ( b 0 + b 1 + b 2 + b 3 + b 4 ) ⋅ 2 0 + ( b 4 + b 5 + b 6 + b 7 ) ⋅ 2 4 + . . . + ( b 28 + b 29 + b 30 + b 31 ) ⋅ 2 28 ) = ( b 0 + b 1 + b 2 + b 3 ) ⋅ 2 0 + ( b 4 + b 5 + b 6 + b 7 ) ⋅ 2 4 + . . . + ( b 28 + b 29 + b 30 + b 31 ) ⋅ 2 28 ) i=((b_0+b_1)\cdot2^0+(b_4+b_5)\cdot2^4+...+(b_{28}+b_{29}\cdot2^{28}))+((b_2+b_3)\cdot2^0+(b_6+b_7)\cdot2^4+...+(b_{30}+b_{31})\cdot2^{28})\\ =(b_0+b_1+b_2+b_3+b_4)\cdot2^0+(b_4+b_5+b_6+b_7)\cdot2^4+...+(b_{28}+b_{29}+b_{30}+b_{31})\cdot2^{28})\\ =(b_0+b_1+b_2+b_3)\cdot2^0+(b_4+b_5+b_6+b_7)\cdot2^4+...+(b_{28}+b_{29}+b_{30}+b_{31})\cdot2^{28}) i=((b0+b1)⋅20+(b4+b5)⋅24+...+(b28+b29⋅228))+((b2+b3)⋅20+(b6+b7)⋅24+...+(b30+b31)⋅228)=(b0+b1+b2+b3+b4)⋅20+(b4+b5+b6+b7)⋅24+...+(b28+b29+b30+b31)⋅228)=(b0+b1+b2+b3)⋅20+(b4+b5+b6+b7)⋅24+...+(b28+b29+b30+b31)⋅228) -
对于
i = (i + (i >>> 4)) & 0x0f0f0f0f;
得到的结果为:
-
对于
i = i + (i >>> 8);
得到的结果为:
-
对于
i = i + (i >>> 16);
得到的结果为:
-
最后,
i & 0x3f;
得到的最终结果为:
i = ∑ i = 0 31 b i i=\sum_{i=0}^{31}b_i i=i=0∑31bi