
本文深入解释为何 (-15) & (-1 >> 1) 的结果仍是 -15,核心在于 Java 有符号右移 >> 会进行符号扩展,导致掩码并非预期的正数,从而影响按位与结果。
本文深入解释为何 `(-15) & (-1 >> 1)` 的结果仍是 -15,核心在于 java 有符号右移 `>>` 会进行符号扩展,导致掩码并非预期的正数,从而影响按位与结果。
在 Java 中,位运算操作严格依赖整数的二进制补码表示。我们来逐步拆解表达式 (-15) & (-1 >> 1) 的执行过程:
1. -1 的二进制表示(32 位 int)
-1 在补码中全部为 1:
11111111 11111111 11111111 11111111
2. -1 >> 1:有符号右移一位
>> 是算术右移(signed right shift),会保留符号位,并用最高位(符号位)填充左侧空出的位置。
因此 -1 >> 1 仍为全 1:
11111111 11111111 11111111 11111111 → 还是 -1
⚠️ 注意:这不是 01111111...(即 Integer.MAX_VALUE),那是无符号右移 >>> 的结果。
验证代码:
System.out.println(Integer.toBinaryString(-1)); // "11111111111111111111111111111111" System.out.println(Integer.toBinaryString(-1 >> 1)); // 同上(截断前导1,但值不变) System.out.println(-1 >> 1); // 输出 -1 System.out.println(-1 >>> 1); // 输出 2147483647(即 0x7FFFFFFF)
3. 按位与运算 (-15) & (-1 >> 1)
由于 -1 >> 1 == -1,原式等价于:
(-15) & (-1)
而任意整数 x & -1 都等于 x(因为 -1 的所有位均为 1,按位与不改变原数任何位):
-15: 11111111 11111111 11111111 11110001 -1: 11111111 11111111 11111111 11111111 AND → 11111111 11111111 11111111 11110001 = -15
✅ 正确做法:如需“清除符号位”,应使用无符号右移 >>>
若目标是构造一个高位为 0、其余为 1 的掩码(如 01111111...),必须使用 >>>:
int mask = -1 >>> 1; // 0x7FFFFFFF → 2147483647 System.out.println((-15) & mask); // 输出 2147483633(即 -15 的符号位被清零后的正值) // 二进制:11110001 → 与 01111111... 按位与后,高位全0,结果为正数
总结
- >> 是算术右移:保留符号位,适用于带符号数值的除法语义(如 x >> 1 ≡ x / 2 向下取整);
- >>> 是逻辑右移:左侧补 0,适用于位掩码构造、无符号处理等场景;
- 对负数直接使用 >> 生成掩码极易引发误解,务必根据语义选择正确的右移操作符。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











