在Java中,将int自身相乘
为什么我用相同的整数乘以在Java中,将int自身相乘,java,int,Java,Int,为什么我用相同的整数乘以int num=2147483647,结果返回1?请注意,我处于int可能值的极限 我已经尝试捕获异常,但仍然将结果设为1。int无法处理任何大值。。在JAVA中,这个问题有一个专用类,它非常方便 import java.math.BigInteger; public class BigIntegerDemo { public static void main(String[] args) { BigInteger b1 = new BigIntege
int num=2147483647
,结果返回1?请注意,我处于int可能值的极限
我已经尝试捕获异常,但仍然将结果设为1。int无法处理任何大值。。在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);
}
}
来源:根据,签名的Java“int”是2^31-1。等于2147483647
因此,如果您已经达到int的最大值,并且如果您将其乘以任何值,我将预期会出现错误。在整数算术中,发生溢出时Java不会引发异常。相反,它只是结果的32个最低有效位,或者等效地,它“环绕”。也就是说,如果计算
2147483647+1
,结果是-2147483648
2147483647平方正好是二进制:
11111111111111111111111111111100000000000000000000000000000001
结果的最低有效32位等于值1
如果要使用不适合32位的值进行计算,则必须在任何乘法之前使用
long
(如果64位足够)或java.math.BigInteger
(如果不足够)。。所以你实际上是想用011111111111111111111111乘以011111111111111111111111。结果是
1111111111111111111111111111111000000000000000000000000000000001. int只能保存32位,因此实际上得到00000000000000000000000000000000000001,它的十进制值为=1。问题似乎是因为int无法处理如此大的值。基于基本类型,允许的最大值范围为2^31-1(2147483647),这与您要乘以的值完全相同 因此,在这种情况下,建议使用容量更大的下一个基本类型,例如,您可以将“int”变量更改为“long”,其范围在-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);
}
int num = 2147483647;
long result = num * num;
if (result != (long)((int)result)) {
// overflow happened
}
输出为:
total: 4611686014132420609
我希望这能帮助你
注意。在给定情况下应该发生的事情的确切规则
如果整数乘法溢出,则结果是数学乘积的低阶位,如某些足够大的2的补码格式所示。因此,如果发生溢出,则结果的符号可能与两个操作数值的数学乘积的符号不同
这意味着,当您将两个int
s相乘时,结果将首先以long
值表示(该类型包含足够的位来表示结果)。然后,因为您将其分配给int
变量,所以较低的位保留在int
中
联合联络小组还说:
尽管可能会发生溢出、下溢或信息丢失,乘法运算符*的计算永远不会引发运行时异常
这就是为什么你从来没有例外
我的猜测是:将结果存储在long
中,并检查如果向下转换到int
会发生什么。例如:
public static void main(String[] args) {
long num = 2147483647L;
long total = num * num;
System.out.println("total: " + total);
}
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位边界分割):
从这个数字中,您得到了最右边的部分,它等于
1
您是否尝试过大整数类如果您希望计算如此大的数字,您不能使用int。您能显示您正在使用的确切代码吗?Java不会为整数溢出抛出异常。如果必须检测它,则必须在long
中进行计算,并检查Integer.MIN\u值
和Integer.MAX\u值
,或使用biginger