为什么我的Java数学错了?
在下面的代码中,我看不出T1和T3有什么不同。当然,我的计算器说它们不是为什么我的Java数学错了?,java,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(St
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。当我在eclipse中使用T1并将鼠标移到变量上时,我会得到一个光泽,显示相同的值
java版本“1.6.0_33”OSX
因为
int
不能大于2147483647,所以您会溢出。最终值不在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,结果与预期一致
要修复它,您需要将数字常量更改为长:
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亿,这比一个整数所能容纳的还要大。所以,一旦它到达2147483647,它接下来将转到-2147483648,依此类推。。因此,对于100亿美元,它是这样的:
2147483647(转到底片,我们还有7852516353)
-2147483648(一直计数到整数.MAX_INT)
2147483647(再次转到负片,我们还有3557549057)
-2147483648(添加剩余的3557549058)
现在我们有了:1410065408正如偏执狂安卓所说,这是一个
int
溢出问题。要了解T3的不同之处,请参见下文
public static final long T1 = 24 * 60 * 60 * 1000 * 30;
这里的所有数字都是int
s,因此这与
public static final long T1 = (long) (24 * 60 * 60 * 1000 * 30);
int
部分溢出,因此对long
的隐式转换来得太迟,无法避免精度损失。
在
您有相同的数字,但它是一个较小的数字,适用于32位int
(31位表示正值)和64位长
public static final long T3 = T2 * 30;
这将long
乘以int
,64位算术也是如此,这就是为什么它有不同的值。相当于
public static final long T3 = T2 * (long) 30;
此处的隐式
long
足够早,可以防止精度损失。可以使用L
而不是L
来表示long
。在许多终端字体中,小写字母l
看起来非常像1
,而l
则不是。实际上,这太好了,太公开了静态最终长T1=24L*60*60*1000*30;“Java从根本上打破了数学吗?”——当然不是@Shark整数溢出。直到有人转换该值,该值才会变为长值。
public static final long T3 = T2 * (long) 30;