Java位运算结果存疑:自定义计算值与实际输出为何不一致?
为什么Java中位运算的结果和预期不符?
嘿,这个问题的核心是你没考虑到Java里的int是32位有符号整数,而且负数是用补码形式存储的——这也是位运算结果和你预期不一样的关键。咱们一步步拆解你的代码和计算过程:
先看你的代码
public class BitShiftOpeartor { public static void main(String[] args) { int y1 = 28; int z1 = -30; System.out.println(y1 & z1); System.out.println(y1 | z1); System.out.println(y1 ^ z1); } }
你的预期 vs 实际输出
预期输出:
28 -30 -2
实际输出:0 -2 -2
接下来咱们逐个分析每个位运算的真实计算过程:
第一步:把数值转换成32位二进制补码
Java的int是32位,正数的补码等于原码,负数的补码是原码取反+1:
- 28(正数)的32位二进制:
00000000 00000000 00000000 00011100 - -30的补码计算:
- 30的原码:
00000000 00000000 00000000 00011110 - 取反(反码):
11111111 11111111 11111111 11100001 - 加1得到补码:
11111111 11111111 11111111 11100010
- 30的原码:
1. 与运算(y1 & z1):28 & -30
与运算规则:对应位都为1时结果为1,否则为0
把两个数的32位二进制按位对比:
28: 00000000 00000000 00000000 00011100 -30补码: 11111111 11111111 11111111 11100010 按位与结果:00000000 00000000 00000000 00000000
结果是32位全0,对应十进制的0——这就是实际输出的第一个值,你之前预期28是因为只考虑了低几位,忽略了-30的高位全是1,而28的高位全是0,与运算后高位全为0,低位也没有同时为1的位。
2. 或运算(y1 | z1):28 | -30
或运算规则:对应位只要有一个1,结果就为1
按位对比:
28: 00000000 00000000 00000000 00011100 -30补码: 11111111 11111111 11111111 11100010 按位或结果:11111111 11111111 11111111 11111110
这个结果是负数的补码,咱们转成十进制:
- 先减1得到反码:
11111111 11111111 11111111 11111101 - 取反得到原码:
00000000 00000000 00000000 00000010(对应十进制2) - 所以最终结果是
-2——这和实际输出一致,你之前预期-30是错误的,因为或运算会把28的有效位也置为1,改变了原来-30的低位。
3. 异或运算(y1 ^ z1):28 ^ -30
异或运算规则:对应位不同时结果为1,相同时为0
按位对比:
28: 00000000 00000000 00000000 00011100 -30补码: 11111111 11111111 11111111 11100010 按位异或结果:11111111 11111111 11111111 11111110
这个结果和或运算的二进制完全一样,转成十进制也是-2——和实际输出一致。
总结一下:你之前的计算错误是因为没有考虑Java中int的32位长度,以及负数的补码存储规则,只关注了低几位的二进制值,忽略了高位的影响。
内容的提问来源于stack exchange,提问作者SRM
相关产品推荐
相关产品推荐

