You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java左移操作相关问题咨询:异常现象解析及丢失信息去向

Java中int左移操作的那些“反直觉”现象解析

嘿,这个左移的坑我刚学Java位操作时也踩过,当时盯着输出愣了半天~咱们来逐个拆解这些现象背后的门道:

1. 为什么-1左移31位得到-2147483648?

先看你的测试代码和输出:

int x = -1 << 31; 
System.out.print(Integer.toBinaryString(-1) + " -1\n"); 
System.out.print(Integer.toBinaryString(x) + " " + x + "\n"); 
// 输出:
// 11111111111111111111111111111111 -1 
// 10000000000000000000000000000000 -2147483648

Java里的int是32位有符号整数,用补码存储。-1的补码是32个连续的1。左移31位时,所有位向左挪31位,右边补31个0,最左边的31个1都被“挤出去”(溢出丢弃),只剩原本最右边的1移到了最高位(符号位),最终二进制就是10000000...0000——这正好是32位int能表示的最小值-2^31(也就是-2147483648),完全符合预期。

2. 为什么-1左移32位还是-1?

这是最容易懵的点,看代码:

int x = -1 << 32; 
System.out.print(Integer.toBinaryString(-1) + " -1\n"); 
System.out.print(Integer.toBinaryString(x) + " " + x + "\n"); 
// 输出:
// 11111111111111111111111111111111 -1 
// 11111111111111111111111111111111 -1

这可不是Java的bug,是语言规范明确规定的行为!对于int类型的移位操作,移位的位数会先做模32运算(取余数)。说白了,你写a << n时,如果n≥32,实际生效的位数是n % 32。所以-1 << 32等价于-1 << 0——左移0位,结果当然还是原数-1。同理,要是你左移33位,就等价于左移1位,结果会是-2。

3. 为什么-2147483648左移1位得到0?

看这段测试:

System.out.println(-2147483648 << 1); // 输出0

-2147483648是int的最小值,它的补码是10000000000000000000000000000000(最高位1,其余全0)。左移1位时,最高位的1直接被溢出丢弃,右边补0,所有位变成全0,对应的十进制就是0,这完全符合左移的规则:溢出的高位直接丢,不留任何痕迹。

关于“左移丢失的信息是否被存储”的问题

答案很明确:不会被存储。Java的所有位操作(左移、右移、无符号右移)中,被移出的比特位都是直接丢弃的,没有任何内置机制会保存这些“丢失”的信息。如果你的业务需要保留溢出的内容,得自己手动处理——比如用更大的类型(比如long)来承接移位结果,这样溢出的位就会存在long的高位里。

内容的提问来源于stack exchange,提问作者OneFlowerOneWorld

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:15:08