为什么我将int num = 2,147,483,647
乘以相同的int num,结果是返回1?请注意,我处于int可能值的限制。
我已经尝试捕获异常,但仍将结果显示为1。
答案 0 :(得分:3)
在任何乘法运算之前,java会将整数转换为二进制数。所以你实际上试图将01111111111111111111111111111111乘以01111111111111111111111111111111。这样的结果是这样的 1111111111111111111111111111111000000000000000000000000000000001.int只能容纳32位,所以实际上你得到的是00000000000000000000000000000001,即十进制的= 1。
答案 1 :(得分:2)
在整数运算中,Java在发生溢出时不会抛出异常。相反,它只是结果的32个最低有效位,或者等价地,它“包裹”。也就是说,如果您计算2147483647 + 1
,则结果为-2147483648
。
2,147,483,647平方正好是二进制:
11111111111111111111111111111100000000000000000000000000000001
结果的最低32位等于值1.
如果要使用不适合32位的值进行计算,则必须使用long
(如果64位足够)或java.math.BigInteger
(如果不是)。
答案 2 :(得分:1)
int无法处理任何大值。Look here。在JAVA中,你有一个专门针对这个问题的课程,非常方便
import java.math.BigInteger;
public class BigIntegerDemo {
public static void main(String[] args) {
BigInteger b1 = new BigInteger("987654321987654321000000000"); //change it to your number
BigInteger b2 = new BigInteger("987654321987654321000000000"); //change it to your number
BigInteger product = b1.multiply(b2);
BigInteger division = b1.divide(b2);
System.out.println("product = " + product);
System.out.println("division = " + division);
}
}
答案 3 :(得分:1)
Java Language Specification确切地规定了在给定情况下会发生什么。
如果整数乘法溢出,则结果是数学乘积的低阶位,如某些足够大的二进制补码格式所示。因此,如果发生溢出,则结果的符号可能与两个操作数值的数学乘积的符号不同。
这意味着,当您将两个int
相乘时,结果将首先以long
值表示(该类型包含足够的位来表示结果)。然后,因为您将其分配给int
变量,所以int
保留较低的位。
JLS还说:
尽管可能发生溢出,下溢或信息丢失,但乘法运算符*的评估从不会引发运行时异常。
这就是为什么你永远不会得到例外。
我的猜测:将结果存储在long
中,并检查如果您向下转换为int
会发生什么。例如:
int num = 2147483647;
long result = num * num;
if (result != (long)((int)result)) {
// overflow happened
}
要真正关注算术,请按照计算:
((2^n)-1) * ((2^n)-1) =
2^(2n) - 2^n - 2^n + 1 =
2^(2n) - 2^(n+1) + 1
在您的情况下,n=31
(您的号码是2 ^ 31 - 1)。结果是2^62 + 2^32 + 1
。在位中它看起来像这样(由32位边界分割):
01000000000000000000000000000001 00000000000000000000000000000001
从这个数字中,你得到最右边的部分,等于1
。
答案 4 :(得分:0)
似乎问题是因为int无法处理如此大的值。基于this link from oracle关于基本类型,允许的最大值范围是2 ^ 31 -1(2,147,483,647),这与您想要乘以的值完全相同。
因此,在这种情况下,建议使用具有更大容量的下一个基本类型,例如,您可以更改" int"变量到"长"它的范围在-2 ^ 63到2 ^ 63-1之间(-9223372036854775808到9223372036854775807)。
例如:
public static void main(String[] args) {
long num = 2147483647L;
long total = num * num;
System.out.println("total: " + total);
}
输出是:
total: 4611686014132420609
我希望这可以帮到你。
问候。
答案 5 :(得分:-1)
根据this link,Java' int'签名是2 ^ 31 - 1.等于2,147,483,647。
因此,如果你已经处于int的最大值,并且如果你将它乘以任何东西,我会发现错误。