探索Integer番外篇之Integer.bitCount(int i)

1. 前言

探索Integer番外篇之Integer.bitCount(int i)_第1张图片
钱不是真正的花掉了,而是换了一种方式陪在你身边

bitCount:统计int类型数值的二进制中1的个数。
在各种版本的面试宝典中,这个题目应该是非常常见的了。比如《剑指offer》面试题10:二进制中1的个数,《编程之美》2.1 求二进制数中1的个数,实现方法非常之多,各有千秋。
我们来看看jdk中是如何实现的。

2. 源码


相比较其他的解法,这个是非常新颖的方式,不愧于大师之笔。

    public static int bitCount(int i) {
        // HD, Figure 5-2
        i = i - ((i >>> 1) & 0x55555555);//第1步
        i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);//第2步
        i = (i + (i >>> 4)) & 0x0f0f0f0f;//第3步
        i = i + (i >>> 8);//第4步
        i = i + (i >>> 16);//第5步
        return i & 0x3f;//第6步
    }

解析过程:
输入 i,
,
其中
要么为0,要么为1,则,统计二进制1的个数,实则求

第1步:i = i - ((i >>> 1) & 0x55555555);
i >>> 1的结果

而0x55555555中 5 表示 0101,与运算就是取奇数位(取第0位,第2位,第4位...),则
(i>>>1) & 0x55555555的结果为

i = i - ((i >>> 1) & 0x55555555)的结果为(2.2+2.3)

第2步:i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
0x33333333中 表示 0011,与运算就是每四位取前两位
i & 0x33333333的结果为

(i>>>2) & 0x33333333的结果为

i = (i & 0x33333333) + ((i>>>2) & 0x33333333)的结果为(2.5 + 2.6)

第3步:i = (i + (i >>> 4)) & 0x0f0f0f0f;
i + (i>>>4)的结果为
\begin{eqnarray*} (b_0+b_1+b_2+b_3+b_4+b_5+b_6+b_7)*2^0 + (b_4+b_5+b_6+b_7+b_8+b_9+b_{10}+b_{11})*2^4 +\\...+(b_{24}+b_{25}+b_{26}+b_{27}+b_{28}+b_{29}+b_{30}+b_{31})*2^{24}+(b_{28}+b_{29}+b_{30}+b_{31})*2^{28} \end{eqnarray*}
而0x0f0f0f0f中,与运算表示每8位取前四位,
则i = (i + (i>>>4)) & 0x0f0f0f0f的结果为

第4步:i = i + (i >>> 8);
i = i + (i>>>8)的结果为
\begin{eqnarray*} i=&(&b_0+b_1+b_2+...+b_{14}+b_{15})*2^0 +(b_8+b_9+b_{10}+...+b_{22}+b_{23})*2^8+ \\&(&b_{24}+b_{25}+b_{26}+...+b_{30}+b_{31})*2^{16} +(b_{24}+b_{25}+b_{26}+...+b_{30}+b_{31})*2^{24} \end{eqnarray*}
第5步:i = i + (i >>> 16);
i = i + (i>>>16)的结果为
\begin{eqnarray*} i=&(&b_0+b_1+b_2+...+b_{30}+b_{31})*2^0 +(b_8+b_9+b_{10}+...+b_{30}+b_{31})*2^8+ \\&(&b_{24}+b_{25}+b_{26}+...+b_{30}+b_{31})*2^{16} +(b_{24}+b_{25}+b_{26}+...+b_{30}+b_{31})*2^{24} \end{eqnarray*}
第5步:i & 0x3f
0x3f表示只取二进制前6位
结果为:

即为二进制1的个数

3.后言

6步法求二进制1的个数,你学会了吗?


探索Integer番外篇之Integer.bitCount(int i)_第2张图片

其他

本人也是在慢慢学习中,如有错误还请原谅、敬请指出,谢谢!

你可能感兴趣的:(探索Integer番外篇之Integer.bitCount(int i))