3

ここで根本的に間違ったことをしているに違いありません。私は非常に単純なコードを持っています:

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

同じ計算を手動で (または Google を使用して) 実行すると、正しい結果が得られます(実際の年は 365 日よりわずかに多いため、妥当な許容範囲内で)。

同じ数学がこのコードでこのような無意味な出力を生成するのはなぜですか?

4

1 に答える 1

13

の値MILLIS_PER_YEARが間違っています。目的の1471228928代わりです31536000000

値の計算を見てください: 関係するすべての値はint値です (Java では、数値の非 10 進数定数はintデフォルトで -values です)。これは、計算の結果intも値になることを意味します。しかし、目的の値は保持できるよりも大きいintため、オーバーフローが発生します。

計算が確実にlong値に対して行われるようにするには、値の少なくとも 1 つを (L接尾辞を追加して) long にします。

private static final long MILLIS_PER_YEAR = 1000L * 60 * 60 * 24 * 365;
于 2012-08-10T07:08:23.450 に答える