/** * Returns an {@code int} value with at most a single one-bit, in the * position of the highest-order ("leftmost") one-bit in the specified * {@code int} value. Returns zero if the specified value has no * one-bits in its two's complement binary representation, that is, if it * is equal to zero. * * @param i the value whose highest one bit is to be computed * @return an {@code int} value with a single one-bit, in the position * of the highest-order one-bit in the specified value, or zero if * the specified value is itself equal to zero. * @since 1.5 */ public static int highestOneBit(int i) { // HD, Figure 3-1 i |= (i >> 1); i |= (i >> 2); i |= (i >> 4); i |= (i >> 8); i |= (i >> 16); return i - (i >>> 1); }
一、第一步的做用是把最高位1右移移位,並與原數據按位取或。那麼這就使得最高位和它的下一位是連續兩個1。
二、第二步的做用是把剛剛移位獲得連續兩個1繼續右移兩位並與原數據按位取或。那麼這就使得最高兩位和它的下兩個連續位組成四個連續的1。
三、以此類推,最終獲得的i是從開始的最高位到結束全是1。並減去i(此時的i已經從最高位開始全1了)不帶符號的右移一位,便可獲得一個int數據的最高位的值。
四、上述狀況是針對於i不爲零和負數的狀況,若是i爲零,那麼獲得的結果始終爲零。若是i位負數,那麼獲得的結果始終是-2147483648。即等於Integer.MIN_VALUE。(緣由在於負數的最高位始終爲1,便是負數的符號位)web
** 此函數的最重要理解點在與要始終把握二進制的最高位進行運算處理,那麼對於函數中的右移一位、兩位、四位、八和十六位就好理解了。** 同理,對於long類型的取最高位運算應該須要加一條語句 i|=(i>>32); 緣由在於long類型在Java中是64位的。
Long類型的hightestOneBit(i)代碼以下:svg
/** * Returns a {@code long} value with at most a single one-bit, in the * position of the highest-order ("leftmost") one-bit in the specified * {@code long} value. Returns zero if the specified value has no * one-bits in its two's complement binary representation, that is, if it * is equal to zero. * * @param i the value whose highest one bit is to be computed * @return a {@code long} value with a single one-bit, in the position * of the highest-order one-bit in the specified value, or zero if * the specified value is itself equal to zero. * @since 1.5 */ public static long highestOneBit(long i) { // HD, Figure 3-1 i |= (i >> 1); i |= (i >> 2); i |= (i >> 4); i |= (i >> 8); i |= (i >> 16); i |= (i >> 32); return i - (i >>> 1); }