を使用してDecimalFormat
いるときに、固定小数点パターンで数値を丸めるときの動作に戸惑いました。より具体的にするために:
double n = 2082809.080589735D;
// Output the exact value of n
System.out.println("value: " + new BigDecimal(n).toPlainString());
System.out.println("double: " + n);
DecimalFormat format = new DecimalFormat("0.00000000");
System.out.println("format: " + format.format(n));
System.out.println("format (BD): " + format.format(new BigDecimal(n)));
このスニペットの出力は次のとおりです。
value: 2082809.080589734949171543121337890625
double: 2082809.080589735
format: 2082809.08058974
format (BD): 2082809.08058973
最初の出力行から、実際の値がと( )の中間点を下回っていることがわかります。それにもかかわらず、引数が指定された場合、値は切り上げられます。2082809.08058973
2082809.08058974
...49...
DecimalFormat
double
その他の値は切り捨てられます。
value: 261285.2738465850125066936016082763671875
double: 261285.273846585
format: 261285.27384658
format (BD): 261285.27384659
これはすべての場合に発生するわけではありません。
value: 0.080589734949171543121337890625
double: 0.08058973494917154
format: 0.08058973
format (BD): 0.08058973
value: 0.2738465850125066936016082763671875
double: 0.2738465850125067
format: 0.27384659
format (BD): 0.27384659
aのフォーマットされた文字列は、問題の実際の数学的値ではなく、の線に沿って生成された不正確な10進値に基づいて、半偶数丸めdouble
を使用して丸められているように見えます。フォーマットされた精度がタイプによって提供される精度に非常に近い(またはそれ以上)場合、物事はややランダムになり始めます。Double.toString()
double
double
上記のすべてのケースで、対応するフォーマットをフォーマットするBigDecimal
と、期待どおりに丸めが実行されるようです。
DecimalFormat
この場合の適切な動作を説明する仕様を見つけることができませんでした。
この動作はどこかに文書化されていますか?
正確さの観点から、実際の数学的値を四捨五入することは望ましいことではないでしょうか。
書く人
1.0...35
は(素朴に?)それが丸められることを期待するだろうと理解しています1.0...4
が1.0...35
、Javaで利用可能なプリミティブデータ型では表現できないかもしれません...
編集:
オラクルにレポートを提出しました。この問題を修正または明確化できることを願っています。