Integer的highestOneBit方法原始碼解析
阿新 • • 發佈:2018-12-06
在讀HashMap原始碼是遇到了highestOneBit這個方法,不懂,看了一下原始碼。
Integer.highestOneBit(i)
這個方法的作用就是取i對應二進位制值最左邊最高位,其餘後面全部補零,並返回對應int型別的值。
highestOneBit方法原始碼如下:
要理解 上述原始碼需要一部分二進位制的基礎,可以去看我的另外一篇文章,JAVA二進位制基礎/** * 將一個整數(二進位制)設定最高位為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 }
我們都知道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
反碼取反獲得負數對應正值 : 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的二進位制