Java:基本数学错误?

时间:2012-08-10 07:04:16

标签: java date time

我必须在这里做一些根本错误的事情。我的代码非常简单:

private static final long MILLIS_PER_YEAR = 1000 * 60 * 60 * 24 * 365;

//...

public long getAge() {
    long millis = System.currentTimeMillis() - this.getBirthdate().getTime();
    System.out.println("Computed age:  " + (millis / MILLIS_PER_YEAR) + ", birthdate=" + this.getBirthdate() + ", birthdateMillis=" 
            + this.getBirthdate().getTime() + ", now=" + new Date() + ", nowMillis=" + System.currentTimeMillis() 
            + ", elapsedMillis=" + millis);
    return millis / MILLIS_PER_YEAR;
}

...但它提供了一些完全不正确的输出:

Computed age:  248, birthdate=2001-01-01 10:00:00.0, birthdateMillis=978307200000, now=Fri Aug 10 16:56:48 EST 2012, nowMillis=1344581808173, elapsedMillis=366274608173
Computed age:  184, birthdate=2004-01-01 10:00:00.0, birthdateMillis=1072915200000, now=Fri Aug 10 16:56:48 EST 2012, nowMillis=1344581808173, elapsedMillis=271666608173

如果我手动运行相同的计算(or by using Google),我会得到correct result(在合理的限额范围内,因为实际年份略多于365天)。

同样的数学在这段代码中产生这种无意义的输出是怎么回事?

1 个答案:

答案 0 :(得分:13)

MILLIS_PER_YEAR的值是错误的。它是1471228928而不是所需的31536000000

查看值的计算:所有参与的值都是int值(数字,非十进制常量是int - 默认情况下在Java中的值)。这意味着计算的结果也将是int值。但是期望的值大于int可以容纳的值,因此您将有溢出。

要确保对long值进行计算,只需将至少一个值设为long(通过附加L后缀):

private static final long MILLIS_PER_YEAR = 1000L * 60 * 60 * 24 * 365;