为什么我的数学在Java中错了?

use*_*245 0 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

那么为什么我得到的输出:

-1702967296
86400000
2592000000
Run Code Online (Sandbox Code Playgroud)

这个示例程序中的不仅仅是System.out.println.当我在日食中使用T1并将鼠标悬停在变量上时,我会得到一个显示相同值的光泽.

java版"1.6.0_33"OSX

rth*_*sen 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 也许使用`L`代替`l`来表示`long`.在许多终端字体中,小写的`l`看起来非常像`1`,而`L`则没有. (7认同)

Mik*_*uel 6

正如偏执的机器人所说,这是一个int溢出问题.要了解T3的不同之处,请参阅下文.

public static final long T1 = 24 * 60 * 60 * 1000 * 30;
Run Code Online (Sandbox Code Playgroud)

这里的所有数字都是ints所以这是相同的

public static final long T1 = (long) (24 * 60 * 60 * 1000 * 30);
Run Code Online (Sandbox Code Playgroud)

int部分溢出,因此隐式转换long到达太晚以避免精度损失.在

public static final long T2 = 24 * 60 * 60 * 1000;
Run Code Online (Sandbox Code Playgroud)

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

public static final long T3 = T2 * 30;
Run Code Online (Sandbox Code Playgroud)

这个值乘以一个long通过int这样做的64位算术这就是为什么它具有不同的值.
它相当于

public static final long T3 = T2 * (long) 30;
Run Code Online (Sandbox Code Playgroud)

这里隐含的long足够早以防止精度损失.