間違った値を出力しません。予期しない値を出力するだけです。
重要な点は、ここで何が起こるかです。
endTime - duration
これは実際には次のように評価されます。
(float) endTime - duration;
ここでデータが失われます。1353728995に最も近いfloat
値は1353729024であり、float
2を引いた結果に最も近い値は1353729024のままです。
これはすべて言語仕様に従います。JLSセクション15.8.2(加算演算子)は、2進数値昇格がオペランドに適用されると述べています。
セクション5.6.2(2進数の昇格)は次のように始まります。
演算子が2進数の昇格をオペランドのペアに適用する場合、各オペランドは数値タイプに変換可能な値を示す必要があり、次の規則が順番に適用されます。
したがって、これらの規則に従って、のlong
値endTime
はに変換されfloat
、減算はfloat
算術で実行されます。
float
のみが有効数字7桁を提供し、残りはかなり明白であることを忘れないでください。
結果をにキャストしないとlong
、コンパイラーは何が起こっているのかをより明確にすることに注意してください。
Test.java:8: error: possible loss of precision
long startTime = endTime - duration;
^
required: long
found: float
1 error
float
これにより、結果がになり、操作がどのように実行されるか、およびどのような精度が期待されるかについて警告ベルが鳴るはずであることがかなり明確になります。