BigDecimalの、分裂&たMathContext - 非常に奇妙な行動
-
22-09-2019 - |
質問
のCentOS 5.4、 OpenJDKのランタイム環境(ビルド1.6.0-B09)
MathContext context = new MathContext(2, RoundingMode.FLOOR);
BigDecimal total = new BigDecimal("200.0", context);
BigDecimal goodPrice = total.divide(BigDecimal.valueOf(3), 2, RoundingMode.FLOOR);
System.out.println("divided price=" + goodPrice.toPlainString());
// prints 66.66
BigDecimal goodPrice2 = total.divide(BigDecimal.valueOf(3), new MathContext(2, RoundingMode.FLOOR));
System.out.println("divided price2=" + goodPrice2.toPlainString());
// prints 66
BUG?
解決
第1の状況のJavadocます:
の値である(本/除数)のBigDecimalを返し、 そしてその規模として指定されています。丸めは、指定されたスケールで結果を生成するために実行する必要がある場合、指定された丸めモードが適用されます。
と第2の状況のJavadocます:
の値である(本/除数)のBigDecimalを返し、 コンテキスト設定に従った丸めでます。
私たちが得るたMathContextのJavadocを参照:
不変オブジェクトどのカプセル化 記述するコンテキスト設定 数値演算子のための一定のルール、 このようなことによって実現したものと BigDecimalクラス。 ベースに依存しません 設定は次のとおりです。精度:数 動作のために使用される桁。 結果は、この精度に丸められます roundingMode:RoundingModeオブジェクト これは、するアルゴリズムを指定します 丸めのために使用されます。
だから、最初のケースでは、あなたは、あなたがラウンド丸めが床関数として実行され、精度の小数点以下2桁に意味、2のスケールを指定しました。第2の演算は、丸めはフロア関数である精度の2桁に丸められ2の指定された精度を有します。だから、最初のケースでは、あなたはの、第二の小数点以下の場所の後に2桁のために尋ねた、あなただけの2桁の数字を求めました。たとえば、あなたがたMathContextで4桁の数字のために求めていた場合、あなたが答えると、あなたは66.66を取得したい。
私はこれはバグがそんなに2つの方法が同じ計算を実行しないことなどであるとは思わないようにします。
他のヒント
これは完全に正常な動作です。私は、あなたがミスを犯すと、(スケール)と精度を丸め混ぜると思います。
total.divide(BigDecimal.valueOf(3), 2, RoundingMode.FLOOR)
ここにあなたがたMathContextを無効にして丸めを使用します。
total.divide(BigDecimal.valueOf(3), new MathContext(2, RoundingMode.FLOOR))
ここであなたは2の精度を設定し、唯一の2桁の数字を受け取ります。
は分割(BigDecimalを、たMathContext)メソッドのJavadocを読んで、文脈の唯一の丸めモードが考慮されると考えられる。