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

Java中两int类型整数相乘转long时溢出问题及显式类型转换必要性的技术问询

关于Java整数乘积溢出与类型转换的问题解答

嘿,这两个问题其实都是Java整数运算里很常见的“坑”,我来给你掰扯清楚:

1. 为什么小输入正常,大输入失效?

Java里的int类型是32位有符号整数,它的取值范围是**-231(-2147483648)到231-1(2147483647)。当你用两个int类型的A和B相乘时,Java会先以int类型来计算乘积——如果这个乘积超出了int的范围,就会发生整数溢出**。

溢出后的结果会按照补码规则循环:比如原本应该是很大的正数,溢出后会变成负数或者一个错误的小正数。就像你遇到的情况,32329×4746475的实际结果远大于2147483647,所以计算后溢出成了-1170032381,这时候while(mul>0)的条件不满足,循环直接跳过,返回0。

而小输入的乘积刚好在int的范围内,不会溢出,所以计算结果正确,循环能正常统计二进制里的1的个数。你测试的5位以内的A和B,它们的乘积大概率没超过2147483647,所以能得到正确结果。

2. 为什么隐式类型转换没生效?

这里的关键是运算符优先级和运算类型的确定时机。Java会先看乘法操作的两个操作数类型:如果两个都是int,那乘法运算就会以int类型执行,得到的结果也是int——哪怕你之后把这个结果赋值给long类型的变量,也只是把已经溢出的int值隐式转成long,溢出的事实已经发生了。

隐式转换生效的前提是,运算时至少有一个操作数是long类型。比如你修改后的(long)A*(long)B,先把A和B都转成long,这时候乘法会以long类型执行(long是64位,范围远大于109×109),自然不会溢出,结果也就正确了。其实你只需要把其中一个转成long就行,比如(long)A*B,因为Java会自动把另一个int隐式转成long再相乘。

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

火山引擎 最新活动