Integer的highestOneBit方法源码解析

           在读HashMap源码是遇到了highestOneBit这个方法,不懂,看了一下源码。

Integer.highestOneBit(i)  
 这个方法的作用就是取i对应二进制值最左边最高位,其余后面全部补零,并返回对应int类型的值。

          highestOneBit方法源码如下:

 /**
     * 将一个整数(二进制)设置最高位为1,其它位为0,然后返回改变后的值
     * 如果这个整数是0返回0
     * @param i
     * @return
     */
    public static int highestOneBit(int i) {
        // 例如1000
        i |= (i >>  1); // 使前2位变为1,相当于i = i | (i >> 1); i = 1000 | 0100 = 1100
        i |= (i >>  2); // 使前4位变为1,由于上一步确保了前两位都是1,所以这一次移动两位,1111
        i |= (i >>  4); // 使前8位变为1,1111
        i |= (i >>  8); // 使前16位变为1,1111
        i |= (i >> 16); // 使前32位变为1,1111
        return i - (i >>> 1); // i >>> 1 无符号右移,使最高位为0,其余位为1,相减即得出结果,1111 - 0111 = 1000 
    }
要理解 上述源码需要一部分二进制的基础,可以去看我的另外一篇文章,JAVA二进制基础 

我们都知道32位的int值取值范围为-2的32次幂到(2的32次幂-1),这是为啥呢?

         因为二进制的最高位为符号位,0表示正数,1表示负数,那么毋庸置疑,

         32位最大值的二进制形式为:

 0111 1111 1111 1111 1111 1111 1111 1111       转化为int类型就是2的32次幂-1

         因为最高位是符号位,负数为1,所以32位的最小值的二进制形式为:

 1111 1111 1111 1111 1111 1111 1111 1111 

         我们知道二进制负数的值是用他对应正值的反码加1来获得,那么可以反向推出他的十进制值

 负数源码:                            1111 1111 1111 1111 1111 1111 1111 1111    

         原码减一获得反码:                 0111 1111 1111 1111 1111 1111 1111 1111   

         反码取反获得负数对应正值 : 1000 0000 0000 0000 0000 0000 0000 0000  2的32次幂

        所以1111 1111 1111 1111 1111 1111 1111 1111 转化为十进制就是 负的2的32次幂。

       下面再来解释,为啥方法中右移了这么多次:

        因为32位的int值最终有32位,所以他总共右移了32位,最终使前32位变为1,然后在进行无符号位右移,用原值减去无符号位右移的值就得到了最高位1其余为0的二进制

      

猜你喜欢

转载自blog.csdn.net/u011544437/article/details/78497190
今日推荐