今天发现在Integer中存在两个方法reverse和reverseBytes以前没有留意过且稍微需要点时间理解,遂写出分析思路。
注:文中为了方便讲述与理解,所有数字表示第x位而非下标。
先看源码:
/**
* Returns the value obtained by reversing the order of the bits in the
* two's complement binary representation of the specified {@code int}
* value.
*
* @param i the value to be reversed
* @return the value obtained by reversing order of the bits in the
* specified {@code int} value.
* @since 1.5
*/
public static int reverse(int i) {
// HD, Figure 7-1
i = (i & 0x55555555) << 1 | (i >>> 1) & 0x55555555;
i = (i & 0x33333333) << 2 | (i >>> 2) & 0x33333333;
i = (i & 0x0f0f0f0f) << 4 | (i >>> 4) & 0x0f0f0f0f;
i = (i << 24) | ((i & 0xff00) << 8) |
((i >>> 8) & 0xff00) | (i >>> 24);
return i;
}
/**
* Returns the value obtained by reversing the order of the bytes in the
* two's complement representation of the specified {@code int} value.
*
* @param i the value whose bytes are to be reversed
* @return the value obtained by reversing the bytes in the specified
* {@code int} value.
* @since 1.5
*/
public static int reverseBytes(int i) {
return ((i >>> 24) ) |
((i >> 8) & 0xFF00) |
((i << 8) & 0xFF0000) |
((i << 24));
}
首先分析reverse:
//将32位二进制位以8位为一个单元编号1-8
//16进制5的二进制0101
//前半段取2、4、6、8位,直接左移一位,用2468替换1357位
//后半段直接右移一位,并取2468位。
//以8位为一个单元,现在编号依据原位置变成21436587
i = (i & 0x55555555) << 1 | (i >>> 1) & 0x55555555;
//16进制3的二进制表现形式是0011
//该计算后43218765
i = (i & 0x33333333) << 2 | (i >>> 2) & 0x33333333;
//16进制f的二进制表现形式为1111
//计算得出87654321
i = (i & 0x0f0f0f0f) << 4 | (i >>> 4) & 0x0f0f0f0f;
最后一步没有写注释。众所周知 1Byte=8 bit。所以该步骤直接可以等同于Integer.reverseBytes(i);
接下来分析reverseBytes
/* i>>>24右移24位,前8位变成后8位(1-8变成24-32)
i右移8位 并& 0xff00取32位中16-24位(8-16变16-24)
i左移8位,并取8-16位(16-24变8-16)
i左移24位(24-32变1-8)*/
return ((i >>> 24) ) |
((i >> 8) & 0xFF00) |
((i << 8) & 0xFF0000) |
((i << 24));
即完成了整个二进制的翻转。