我看到一些用 Java 进行整数相乘的奇怪行为。我正在做一些编码练习,并发现了以下嘶嘶声类型的练习。要求:给定一个整数,编写一个函数,找出小于给定整数的每个 3 的倍数的乘积,except5 的任意倍数。例如,给定 17,我们要返回 12*9*6*3 (= 1944)。我写了以下内容:
public int findProduct(int limit) {
int product = 1;
for(int n = 3; n < limit; n = n + 3) {
if (n % 5 != 0) {
product = product * n;
}
}
return product;
}
这对于少数人来说效果很好。然而在测试中我发现一旦你达到 33 以上,返回值就相差甚远。例如,如果我调用限制为 36 的函数,它将返回 -1.466221696E9。这就是我感到困惑的地方。我正在乘法positive整数,结果在某种程度上是负数。
然而,我发现如果你声明一个双精度数,它似乎总是返回正确的结果。
public double findProduct(int limit) {
double product = 1;
for(int n = 3; n < limit; n = n + 3) {
if (n % 5 != 0) {
product = product * n;
}
}
return product;
}
我的问题是:为什么整数会发生这种情况?双精度类型有什么不同可以使其正确执行?
让我们通过一个例子来检验这一点Integer
.
Integer.MAX_VALUE
可以表示为01111111111111111111111111111111
这是一个32
位长字符串(包括符号位)。现在如果你碰巧添加1
对于上面的字符串,结果是10000000000000000000000000000000
这与Integer.MIN_VALUE
。这称为溢出Integer
.
System.out.println(Integer.toBinaryString(Integer.MAX_VALUE));
// 1111111111111111111111111111111
根据Integer#toBinaryString:
The unsigned integer value is the argument plus 232 if the argument is negative; otherwise it is equal to the argument. This value is converted to a string of ASCII digits in binary (base 2) with no extra leading 0s.
这就是为什么你看不到符号位但看到实际值的原因Integer.MAX_VALUE
is 01111111111111111111111111111111
。现在看一下这段代码:
System.out.println(Integer.toBinaryString(Integer.MAX_VALUE + 1));
// 10000000000000000000000000000000
System.out.println(Integer.toBinaryString(Integer.MIN_VALUE));
// 10000000000000000000000000000000
两个数字的输出是相同的。 Java 无法防范Integer
溢出。开发商应该解决这个问题。那么这个问题的可能解决方案是什么?您可以使用其他数据类型,例如long
or BigInteger。以下是您可能感兴趣的最大值:
System.out.println(Integer.MAX_VALUE); // 2147483647
System.out.println(Long.MAX_VALUE); // 9223372036854775807
System.out.println(Double.MAX_VALUE); // 1.7976931348623157E308
System.out.println(Float.MAX_VALUE); // 3.4028235E38
一旦Integer
达到MAX_VALUE
它会开始溢出,最终会得到负值。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)