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

为何int连乘后转long结果错误?ci1值异常原因解析

解答:int类型相乘溢出与类型提升问题

咱们直接来解决你的两个疑问,再拆解背后的细节:

1. 为什么变量ci1会存储错误的值?

核心原因是int类型的溢出im1是int类型,当你执行im1 * im1 * im1的时候,所有乘法运算都是在int的取值范围内进行的。咱们算个数:63360的三次方是254358061056000,这可比int类型的最大值(2^31-1,也就是2147483647)大太多了。

Java里整数溢出不会抛出任何异常,只会偷偷截断超出32位的二进制数据,得到一个错误的数值,之后再把这个错值赋值给long类型的ci1——这时候再转long也没用,数据已经丢了,所以ci1就存了错误的结果。

2. 将三个int类型数值相乘后转换为long类型时,究竟发生了什么?

这里的关键是Java的类型提升规则

  • ci1的情况:先让三个int相乘,结果还是int,已经溢出变错了,再转long也救不回来。
  • im2是long类型,当你算im2 * im2 * im2时,Java会自动把所有参与运算的数都提升成long类型(只要运算里有一个long,其他整数类型都会跟着转long)。long的最大值是2^63-1,完全装得下63360的三次方,所以整个运算都在安全的范围内,结果自然是对的。

额外补充:怎么避免这种溢出?

如果手头是int变量,但想计算乘积不溢出,只要在运算前把其中一个变量转成long就行,比如:

ci1 = (long)im1 * im1 * im1;

这样第一个乘法就会触发类型提升,后面的运算都在long范围内进行,结果就正确了。


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

火山引擎 最新活动