为什么我的数学错误在Java?

时间:2012-07-29 03:47:10

标签: 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并将鼠标悬停在变量上时,我会得到一个显示相同值的光泽。

  

java版“1.6.0_33”OSX

3 个答案:

答案 0 :(得分:8)

因为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);
    }
}

答案 1 :(得分:6)

正如paranoid-android所说,这是一个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的隐式转换太晚到达以避免精度损失。 在

public static final long T2 = 24 * 60 * 60 * 1000;

你有相同的但它的数字较小,适合32位int(正值为31位)和64位long

public static final long T3 = T2 * 30;

这会将longint相乘,因此64位算术也就是它具有不同值的原因。 它相当于

public static final long T3 = T2 * (long) 30;

此处的隐式long足够早以防止精度损失。

答案 2 :(得分:1)

这是因为在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亿,这比整数可以容纳的要大。所以,一旦达到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