整数翻转

深入解析Java中Integer.reverse(int i)方法实现原理,通过巧妙的位操作完成二进制位的翻转,理解其背后的算法逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前几天在写道进制翻转的题目,发现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;
}

这是什么神仙代码?一眼看过去丈二和尚摸不着头脑。

仔细推敲后发现:

不妨设iii的二进制如下:

1234567891011121314151617181920212223242526272829303132
b1b_{1}b1b2b_{2}b2b3b_{3}b3b4b_{4}b4b5b_{5}b5b6b_{6}b6b7b_{7}b7b8b_{8}b8b9b_{9}b9b10b_{10}b10b11b_{11}b11b12b_{12}b12b13b_{13}b13b14b_{14}b14b15b_{15}b15b16b_{16}b16b17b_{17}b17b18b_{18}b18b19b_{19}b19b20b_{20}b20b21b_{21}b21b22b_{22}b22b23b_{23}b23b24b_{24}b24b25b_{25}b25b26b_{26}b26b27b_{27}b27b28b_{28}b28b29b_{29}b29b30b_{30}b30b31b_{31}b31b32b_{32}b32

0x55555555二进制:0101 0101 0101 0101 0101 0101 0101 0101

所以很容易发现:

(i & 0x55555555) << 1的结果是:取出iii的偶数位(左移末尾补0),结果如下:记为i1i_1i1

1234567891011121314151617181920212223242526272829303132
b2b_{2}b20b4b_{4}b40b6b_{6}b60b8b_{8}b80b10b_{10}b100b12b_{12}b120b14b_{14}b140b16b_{16}b160b18b_{18}b180b20b_{20}b200b22b_{22}b220b24b_{24}b240b26b_{26}b260b28b_{28}b280b30b_{30}b300b32b_{32}b320

(i >>> 1) & 0x55555555的结果是:取出iii的奇数为(无符号左移首位补0),结果如下:记为i2i_2i2

1234567891011121314151617181920212223242526272829303132
0b1b_{1}b10b3b_{3}b30b5b_{5}b50b7b_{7}b70b9b_{9}b90b11b_{11}b110b13b_{13}b130b15b_{15}b150b17b_{17}b170b19b_{19}b190b21b_{21}b210b23b_{23}b230b25b_{25}b250b27b_{27}b270b29b_{29}b290b31b_{31}b31

再将i1i_1i1、记为i2i_2i2按位取运算,结果如下:

1234567891011121314151617181920212223242526272829303132
b2b_{2}b2b1b_{1}b1b4b_{4}b4b3b_{3}b3b6b_{6}b6b5b_{5}b5b8b_{8}b8b7b_{7}b7b10b_{10}b10b9b_{9}b9b12b_{12}b12b11b_{11}b11b14b_{14}b14b13b_{13}b13b16b_{16}b16b15b_{15}b15b18b_{18}b18b17b_{17}b17b20b_{20}b20b19b_{19}b19b22b_{22}b22b21b_{21}b21b24b_{24}b24b23b_{23}b23b26b_{26}b26b25b_{25}b25b28b_{28}b28b27b_{27}b27b30b_{30}b30b29b_{29}b29b32b_{32}b32b31b_{31}b31

可以看出i = (i & 0x55555555) << 1 | (i >>> 1) & 0x55555555;的作用便是将iii中的每两个相邻位交换位置

同理:

0x33333333二进制:0011 0011 0011 0011 0011 0011 0011 0011

所以应当是每四位中的相邻两位交换,结果如下:

1234567891011121314151617181920212223242526272829303132
b4b_{4}b4b3b_{3}b3b2b_{2}b2b1b_{1}b1b8b_{8}b8b7b_{7}b7b6b_{6}b6b5b_{5}b5b12b_{12}b12b11b_{11}b11b10b_{10}b10b9b_{9}b9b16b_{16}b16b15b_{15}b15b14b_{14}b14b13b_{13}b13b20b_{20}b20b19b_{19}b19b18b_{18}b18b17b_{17}b17b24b_{24}b24b23b_{23}b23b22b_{22}b22b21b_{21}b21b28b_{28}b28b27b_{27}b27b26b_{26}b26b25b_{25}b25b32b_{32}b32b31b_{31}b31b30b_{30}b30b29b_{29}b29

0x0f0f0f0f二进制:0000 1111 0000 1111 0000 1111 0000 1111

所以应当是每 八位中的相邻四位交换,结果如下:

1234567891011121314151617181920212223242526272829303132
b8b_{8}b8b7b_{7}b7b6b_{6}b6b5b_{5}b5b4b_{4}b4b3b_{3}b3b2b_{2}b2b1b_{1}b1b16b_{16}b16b15b_{15}b15b14b_{14}b14b13b_{13}b13b12b_{12}b12b11b_{11}b11b10b_{10}b10b9b_{9}b9b24b_{24}b24b23b_{23}b23b22b_{22}b22b21b_{21}b21b20b_{20}b20b19b_{19}b19b18b_{18}b18b17b_{17}b17b32b_{32}b32b31b_{31}b31b30b_{30}b30b29b_{29}b29b28b_{28}b28b27b_{27}b27b26b_{26}b26b25b_{25}b25

到最后一步:

i = (i << 24) | ((i & 0xff00) << 8) | ((i >>> 8) & 0xff00) | (i >>> 24);

注意:0xff00实际上是0x0000ff00

(i << 24)结果:

1234567891011121314151617181920212223242526272829303132
b32b_{32}b32b31b_{31}b31b30b_{30}b30b29b_{29}b29b28b_{28}b28b27b_{27}b27b26b_{26}b26b25b_{25}b25000000000000000000000000

(i & 0xff00) << 8 结果:

1234567891011121314151617181920212223242526272829303132
00000000b24b_{24}b24b23b_{23}b23b22b_{22}b22b21b_{21}b21b20b_{20}b20b19b_{19}b19b18b_{18}b18b17b_{17}b170000000000000000

(i >>> 8) & 0xff00 结果:

1234567891011121314151617181920212223242526272829303132
0000000000000000b16b_{16}b16b15b_{15}b15b14b_{14}b14b13b_{13}b13b12b_{12}b12b11b_{11}b11b10b_{10}b10b9b_{9}b900000000

(i >>> 24)结果:

1234567891011121314151617181920212223242526272829303132
000000000000000000000000b8b_{8}b8b7b_{7}b7b6b_{6}b6b5b_{5}b5b4b_{4}b4b3b_{3}b3b2b_{2}b2b1b_{1}b1

然后在取或运算,得到最后的翻转结果:

1234567891011121314151617181920212223242526272829303132
b32b_{32}b32b31b_{31}b31b30b_{30}b30b29b_{29}b29b28b_{28}b28b27b_{27}b27b26b_{26}b26b25b_{25}b25b24b_{24}b24b23b_{23}b23b22b_{22}b22b21b_{21}b21b20b_{20}b20b19b_{19}b19b18b_{18}b18b17b_{17}b17b16b_{16}b16b15b_{15}b15b14b_{14}b14b13b_{13}b13b12b_{12}b12b11b_{11}b11b10b_{10}b10b9b_{9}b9b8b_{8}b8b7b_{7}b7b6b_{6}b6b5b_{5}b5b4b_{4}b4b3b_{3}b3b2b_{2}b2b1b_{1}b1

太神奇了!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值