为什么我的Java数学错了?
在下面的代码中,我看不出T1和T3有什么不同。当然,我的计算器说它们不是
public class longTest {
public static final long T1 = 24 * 60 * 60 * 1000 * 30;
public static final long T2 = 24 * 60 * 60 * 1000;
public static final long T3 = T2 * 30;
public static void main(String[] args) {
System.out.println(T1);
System.out.println(T2);
System.out.println(T3);
}
}
那么,我为什么要得到以下结果:
-1702967296
86400000
2592000000
这不仅仅是系统。出来println也在这个示例程序中。当我在eclipse中使用T1并将鼠标移到变量上时,我会得到一个光泽,显示相同的值
java version "1.6.0_33" OSX
# 1 楼答案
正如偏执的安卓所说,这是一个溢出问题。要了解T3的不同之处,请参见下文
这里所有的数字都是
int
,所以这和int
部分溢出,因此对long
的隐式转换来得太迟,无法避免精度损失。 在你有相同的数字,但它是一个较小的数字,适合32位
int
(31位为正值)和64位long
它将一个
long
乘以一个int
,64位算术也是如此,这就是为什么它有不同的值相当于
这里的隐式
long
足够早,可以防止精度损失# 2 楼答案
因为
int
不能大于2147483647,所以会出现溢出。最终值不在long
类型的范围之外,但算术本身将数字视为int
,除非您明确声明它们是long
值试试这个:
# 3 楼答案
这是因为在
T1
中,所有的数字都是整数,所以数学运算是对整数执行的,然后分配给一个长整数T3
是将一个Long与一个整数相乘,因此它在进行数学运算时使用Long,结果与预期一致要修复它,您需要将数字常量更改为long:
要理解为什么会得到一个负数:当它到达最大的正数(2^31-1)时,它会绕到最大的负数(-2^31)并从那里上升。这种包装可能会发生多次,因此当您这样做时:
你得到100亿,这比一个整数所能容纳的还要大。所以,一旦它到达2147483647,它接下来会到达-2147483648,以此类推。。所以,对于100亿美元,它是这样的:
2147483647(转到底片,我们还有7852516353)
-2147483648(一直数到整数MAX_INT)
2147483647(再次转为负片,我们还有3557549057)
-2147483648(添加剩余的3557549058)
现在我们有:1410065408