Java左移运算原理解析:为何代码最终输出-32?
解析Java代码左移后输出-32的原因
首先明确两个核心前提:
- Java的
int是32位有符号整数,采用补码存储,最高位(第31位,从0开始计数)为符号位:0代表正数,1代表负数。 - 左移操作
<<的规则是:所有二进制位向左移动指定位数,左边超出的位直接丢弃,右边补0;当移位后符号位变为1时,需通过补码规则计算十进制值。
一步步拆解移位过程
初始值 num = 0xFFFFFFE,先把它转换成32位二进制(补全前导0):
0000 1111 1111 1111 1111 1111 1111 1110
对应的十进制是268435454,和后续移位的倍数关系完全对应。
第1次左移(i=0)
所有位左移1位,右边补0:
0001 1111 1111 1111 1111 1111 1111 1100
十进制值:268435454 * 2 = 536870908,和输出一致。
第2次左移(i=1)
再次左移1位:
0011 1111 1111 1111 1111 1111 1111 1000
十进制值:536870908 * 2 = 1073741816,和输出一致。
第3次左移(i=2)
再次左移1位:
0111 1111 1111 1111 1111 1111 1111 0000
十进制值:1073741816 * 2 = 2147483632,此时符号位还是0,依然是正数。
第4次左移(i=3)
这是关键的一次移位:
所有位左移1位后,原来的第30位(1)移动到第31位(符号位),左边的0被丢弃,右边补0,得到补码形式:
1111 1111 1111 1111 1111 1111 1110 0000
因为符号位是1,这是一个负数,需要通过补码转原码的规则计算十进制:
- 补码减1得到反码:
1111 1111 1111 1111 1111 1111 1101 1111 - 反码按位取反(符号位不变)得到原码:
1000 0000 0000 0000 0000 0000 0010 0000
原码的数值部分是0010 0000,对应十进制32,加上负号后就是-32。
内容的提问来源于stack exchange,提问作者MAGistr
相关产品推荐
相关产品推荐

