1. 程式人生 > >Integer的highestOneBit方法原始碼解析

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的二進位制