Java算术右移和逻辑右移比较

265 阅读2分钟

在 Java 中,有两种右移运算符:

  1. >>(算术右移,有符号右移)

    • 高位补符号位(即正数补 0,负数补 1)。
    • 右移 n 位,相当于除以 2^n,并保留符号
  2. >>>(逻辑右移,无符号右移)

    • 高位永远补 0,不管正数还是负数。
    • 只考虑二进制位的移动,不考虑符号。

🚀 示例对比

public class Main {
    public static void main(String[] args) {
        int num1 = 8;  // 00000000 00000000 00000000 00001000 (十进制 8)
        int num2 = -8; // 11111111 11111111 11111111 11111000 (十进制 -8,二进制补码)

        System.out.println(num1 >> 1);  // 右移 1 位: 00000000 00000000 00000000 00000100 (4)
        System.out.println(num1 >>> 1); // 逻辑右移 1 位:00000000 00000000 00000000 00000100 (4)

        System.out.println(num2 >> 1);  // 算术右移 1 位: 11111111 11111111 11111111 11111100 (-4)
        System.out.println(num2 >>> 1); // 逻辑右移 1 位: 01111111 11111111 11111111 11111100 (2147483644)
    }
}

📌 运行结果

4
4
-4
2147483644

🔹 详细分析

  1. num1 = 8

    • 8 >> 10000100000000100(补 0,结果仍然是 4)。
    • 8 >>> 10000100000000100(补 0,结果还是 4)。
  2. num2 = -8

    • -8 >> 11111100011111100(补 1,结果仍然是 -4)。
    • -8 >>> 11111100001111100(补 0,结果变成大正数 2147483644)。

📌 结论

运算符运算方式高位补充正数示例负数示例
>>(算术右移)除以 2^n保留符号补符号位(正数补 0,负数补 18 >> 1 = 4-8 >> 1 = -4
>>>(逻辑右移)纯粹右移,不考虑符号一律补 08 >>> 1 = 4-8 >>> 1 = 2147483644(变成大正数)

⚠️ 注意>>> 在负数时会导致溢出变成一个很大的正数,因为 Java 没有 unsigned int 类型。


💡 什么时候用 >>,什么时候用 >>>

>>(算术右移)

  • 保留正负号,适用于一般情况,如 x / 2
  • 适用于:除法、符号位需要保留的情况。

>>>(逻辑右移)

  • 适用于无符号数据处理,比如二进制位操作、哈希函数等。
  • 适用于:忽略符号位的二进制运算。

🎯 现在你完全理解了 Java 的右移运算! 🚀