为什么我的数学在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
这个示例程序中的不仅仅是System.out.println。 当我在日食中使用T1并将鼠标hover在变量上时,我会得到一个显示相同值的光泽。
java版“1.6.0_33”OSX
正如paranoid-android所说,这是一个int
溢出问题。 要了解T3的不同之处,请参阅下文。
public static final long T1 = 24 * 60 * 60 * 1000 * 30;
这里的所有数字都是int
所以这是相同的
public static final long T1 = (long) (24 * 60 * 60 * 1000 * 30);
int
部分溢出,因此long
的隐式转换到达太晚以避免精度损失。 在
public static final long T2 = 24 * 60 * 60 * 1000;
你有相同的但它的数字较小,适合32位int
(正值为31位)和64位long
。
public static final long T3 = T2 * 30;
这将long
乘以一个int
因此64位算术就是这样,这就是它具有不同值的原因。
它相当于
public static final long T3 = T2 * (long) 30;
这里隐含的long
,足以防止精度损失。
你得溢出因为int
不能大于2,147,483,647。 最终值不在long
类型的范围之外,但算术本身将数字视为int
除非您明确声明它们是long
值。
尝试这个:
public class LongTest { public static final long T1 = 24L * 60 * 60 * 1000 * 30; public static final long T2 = 24L * 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); } }
这是因为在T1
,所有数字都是整数,因此数学运算在整数上执行,然后分配给长整数。 T3
将Long与整数相乘,因此在进行数学运算时使用Long,结果与预期一致。
要修复它,您需要将数字常量更改为long:
public class longTest { public static final long T1 = 24L * 60L * 60L * 1000L * 30L; 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); } }
要理解为什么你得到一个负数:当它达到最大的正数(2 ^ 31 -1)时,它会回绕到最大的负数(-2 ^ 31)并从那里上升。 这种包装可以多次发生,所以当你这样做时:
public static final int T4 = 100 * 100 * 100 * 100 * 100;// = 1410065408 WHAT!?!?
你得到100亿,这比整数可以容纳的要大。 所以,一旦它达到2,147,483,647,它接下来是-2,147,483,648等等。所以,对于100亿,它是这样的:
2,147,483,647(滚动到底片,我们还剩下7,852,516,353)
-2,147,483,648(一直计算到Integer.MAX_INT)
2,147,483,647(再次转为负数,我们还有3,557,549,057)
-2,147,483,648(加上剩余的3,557,549,058)
现在我们有:1,410,065,408