前几天在写道进制翻转的题目,发现JAVA提供了直接调用的方法
Integer.reverse(int i)
:二进制按位反转
很好奇点进去发现,源码如下:
/**
* 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;
}
这是什么神仙代码?一眼看过去丈二和尚摸不着头脑。
仔细推敲后发现:
不妨设 i i i的二进制如下:
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
b 1 b_{1} b1 | b 2 b_{2} b2 | b 3 b_{3} b3 | b 4 b_{4} b4 | b 5 b_{5} b5 | b 6 b_{6} b6 | b 7 b_{7} b7 | b 8 b_{8} b8 | b 9 b_{9} b9 | b 10 b_{10} b10 | b 11 b_{11} b11 | b 12 b_{12} b12 | b 13 b_{13} b13 | b 14 b_{14} b14 | b 15 b_{15} b15 | b 16 b_{16} b16 | b 17 b_{17} b17 | b 18 b_{18} b18 | b 19 b_{19} b19 | b 20 b_{20} b20 | b 21 b_{21} b21 | b 22 b_{22} b22 | b 23 b_{23} b23 | b 24 b_{24} b24 | b 25 b_{25} b25 | b 26 b_{26} b26 | b 27 b_{27} b27 | b 28 b_{28} b28 | b 29 b_{29} b29 | b 30 b_{30} b30 | b 31 b_{31} b31 | b 32 b_{32} b32 |
0x55555555
二进制:0101 0101 0101 0101 0101 0101 0101 0101
所以很容易发现:
(i & 0x55555555) << 1
的结果是:取出
i
i
i的偶数位(左移末尾补0),结果如下:记为
i
1
i_1
i1
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
b 2 b_{2} b2 | 0 | b 4 b_{4} b4 | 0 | b 6 b_{6} b6 | 0 | b 8 b_{8} b8 | 0 | b 10 b_{10} b10 | 0 | b 12 b_{12} b12 | 0 | b 14 b_{14} b14 | 0 | b 16 b_{16} b16 | 0 | b 18 b_{18} b18 | 0 | b 20 b_{20} b20 | 0 | b 22 b_{22} b22 | 0 | b 24 b_{24} b24 | 0 | b 26 b_{26} b26 | 0 | b 28 b_{28} b28 | 0 | b 30 b_{30} b30 | 0 | b 32 b_{32} b32 | 0 |
(i >>> 1) & 0x55555555
的结果是:取出
i
i
i的奇数为(无符号左移首位补0),结果如下:记为
i
2
i_2
i2
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | b 1 b_{1} b1 | 0 | b 3 b_{3} b3 | 0 | b 5 b_{5} b5 | 0 | b 7 b_{7} b7 | 0 | b 9 b_{9} b9 | 0 | b 11 b_{11} b11 | 0 | b 13 b_{13} b13 | 0 | b 15 b_{15} b15 | 0 | b 17 b_{17} b17 | 0 | b 19 b_{19} b19 | 0 | b 21 b_{21} b21 | 0 | b 23 b_{23} b23 | 0 | b 25 b_{25} b25 | 0 | b 27 b_{27} b27 | 0 | b 29 b_{29} b29 | 0 | b 31 b_{31} b31 |
再将 i 1 i_1 i1、记为 i 2 i_2 i2按位取或运算,结果如下:
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
b 2 b_{2} b2 | b 1 b_{1} b1 | b 4 b_{4} b4 | b 3 b_{3} b3 | b 6 b_{6} b6 | b 5 b_{5} b5 | b 8 b_{8} b8 | b 7 b_{7} b7 | b 10 b_{10} b10 | b 9 b_{9} b9 | b 12 b_{12} b12 | b 11 b_{11} b11 | b 14 b_{14} b14 | b 13 b_{13} b13 | b 16 b_{16} b16 | b 15 b_{15} b15 | b 18 b_{18} b18 | b 17 b_{17} b17 | b 20 b_{20} b20 | b 19 b_{19} b19 | b 22 b_{22} b22 | b 21 b_{21} b21 | b 24 b_{24} b24 | b 23 b_{23} b23 | b 26 b_{26} b26 | b 25 b_{25} b25 | b 28 b_{28} b28 | b 27 b_{27} b27 | b 30 b_{30} b30 | b 29 b_{29} b29 | b 32 b_{32} b32 | b 31 b_{31} b31 |
可以看出i = (i & 0x55555555) << 1 | (i >>> 1) & 0x55555555;
的作用便是将
i
i
i中的每两个相邻位交换位置
同理:
0x33333333
二进制:0011 0011 0011 0011 0011 0011 0011 0011
所以应当是每四位中的相邻两位交换,结果如下:
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
b 4 b_{4} b4 | b 3 b_{3} b3 | b 2 b_{2} b2 | b 1 b_{1} b1 | b 8 b_{8} b8 | b 7 b_{7} b7 | b 6 b_{6} b6 | b 5 b_{5} b5 | b 12 b_{12} b12 | b 11 b_{11} b11 | b 10 b_{10} b10 | b 9 b_{9} b9 | b 16 b_{16} b16 | b 15 b_{15} b15 | b 14 b_{14} b14 | b 13 b_{13} b13 | b 20 b_{20} b20 | b 19 b_{19} b19 | b 18 b_{18} b18 | b 17 b_{17} b17 | b 24 b_{24} b24 | b 23 b_{23} b23 | b 22 b_{22} b22 | b 21 b_{21} b21 | b 28 b_{28} b28 | b 27 b_{27} b27 | b 26 b_{26} b26 | b 25 b_{25} b25 | b 32 b_{32} b32 | b 31 b_{31} b31 | b 30 b_{30} b30 | b 29 b_{29} b29 |
0x0f0f0f0f
二进制:0000 1111 0000 1111 0000 1111 0000 1111
所以应当是每 八位中的相邻四位交换,结果如下:
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
b 8 b_{8} b8 | b 7 b_{7} b7 | b 6 b_{6} b6 | b 5 b_{5} b5 | b 4 b_{4} b4 | b 3 b_{3} b3 | b 2 b_{2} b2 | b 1 b_{1} b1 | b 16 b_{16} b16 | b 15 b_{15} b15 | b 14 b_{14} b14 | b 13 b_{13} b13 | b 12 b_{12} b12 | b 11 b_{11} b11 | b 10 b_{10} b10 | b 9 b_{9} b9 | b 24 b_{24} b24 | b 23 b_{23} b23 | b 22 b_{22} b22 | b 21 b_{21} b21 | b 20 b_{20} b20 | b 19 b_{19} b19 | b 18 b_{18} b18 | b 17 b_{17} b17 | b 32 b_{32} b32 | b 31 b_{31} b31 | b 30 b_{30} b30 | b 29 b_{29} b29 | b 28 b_{28} b28 | b 27 b_{27} b27 | b 26 b_{26} b26 | b 25 b_{25} b25 |
到最后一步:
i = (i << 24) | ((i & 0xff00) << 8) | ((i >>> 8) & 0xff00) | (i >>> 24);
注意:0xff00
实际上是0x0000ff00
(i << 24)
结果:
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
b 32 b_{32} b32 | b 31 b_{31} b31 | b 30 b_{30} b30 | b 29 b_{29} b29 | b 28 b_{28} b28 | b 27 b_{27} b27 | b 26 b_{26} b26 | b 25 b_{25} b25 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
(i & 0xff00) << 8
结果:
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | b 24 b_{24} b24 | b 23 b_{23} b23 | b 22 b_{22} b22 | b 21 b_{21} b21 | b 20 b_{20} b20 | b 19 b_{19} b19 | b 18 b_{18} b18 | b 17 b_{17} b17 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
(i >>> 8) & 0xff00
结果:
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | b 16 b_{16} b16 | b 15 b_{15} b15 | b 14 b_{14} b14 | b 13 b_{13} b13 | b 12 b_{12} b12 | b 11 b_{11} b11 | b 10 b_{10} b10 | b 9 b_{9} b9 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
(i >>> 24)
结果:
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | b 8 b_{8} b8 | b 7 b_{7} b7 | b 6 b_{6} b6 | b 5 b_{5} b5 | b 4 b_{4} b4 | b 3 b_{3} b3 | b 2 b_{2} b2 | b 1 b_{1} b1 |
然后在取或运算,得到最后的翻转结果:
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
b 32 b_{32} b32 | b 31 b_{31} b31 | b 30 b_{30} b30 | b 29 b_{29} b29 | b 28 b_{28} b28 | b 27 b_{27} b27 | b 26 b_{26} b26 | b 25 b_{25} b25 | b 24 b_{24} b24 | b 23 b_{23} b23 | b 22 b_{22} b22 | b 21 b_{21} b21 | b 20 b_{20} b20 | b 19 b_{19} b19 | b 18 b_{18} b18 | b 17 b_{17} b17 | b 16 b_{16} b16 | b 15 b_{15} b15 | b 14 b_{14} b14 | b 13 b_{13} b13 | b 12 b_{12} b12 | b 11 b_{11} b11 | b 10 b_{10} b10 | b 9 b_{9} b9 | b 8 b_{8} b8 | b 7 b_{7} b7 | b 6 b_{6} b6 | b 5 b_{5} b5 | b 4 b_{4} b4 | b 3 b_{3} b3 | b 2 b_{2} b2 | b 1 b_{1} b1 |
太神奇了!!!