You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Java中两条左移位代码结果不同的原因:位运算与溢出分析

为什么这两行Java移位代码执行结果不同?

嘿,这个问题真的戳中了Java位运算里很容易被忽略的细节!我刚学Java的时候也被这个坑绊倒过,咱们一点点把它掰明白:

首先得记住Java里int类型是32位的有符号整数,而且移位运算的规则里有个很关键的点:当你对int类型做移位操作时,移位的位数会先被对32取模(如果是long类型就是对64取模)。这是Java语言规范里明确规定的,目的是避免无意义的超大位数移位。

拆解第一行代码:System.out.println(a << 32);

这里a是1,移位位数是32。按照规则,32对32取模等于0,所以这行代码其实等价于a << 0——移位0位,结果当然还是原来的1啦!

拆解第二行代码:System.out.println(a << 31 << 1);

这行是分步执行的,咱们拆成两步看:

  1. 第一步:1 << 31。31小于32,不需要取模,直接移位。1的二进制是00000000 00000000 00000000 00000001,左移31位后变成10000000 00000000 00000000 00000000,也就是int类型的最小值-2147483648
  2. 第二步:把第一步的结果再左移1位。这时候移位位数是1,取模32还是1,所以把-2147483648的二进制左移1位——最左边的那个1会被移出int的32位范围,剩下的所有位都是0,结果自然就是0了。

简单总结一下:第一行因为移位位数取模后变成0,等于没移位;第二行是两次合法的移位,第一次移到int的边界,第二次移位直接把符号位移出,导致结果归零。

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

火山引擎 最新活动