"新しいBigDecimal(13.3D)結果が不正確であり"13.3000000000000007105.."?
-
19-08-2019 - |
質問
どのようにするJavaの BigDecimal
できるこの苦しい?
Double d = 13.3D;
BigDecimal bd1 = new BigDecimal(d);
BigDecimal bd2 = new BigDecimal(String.valueOf(d));
System.out.println("RESULT 1: "+bd1.toString());
System.out.println("RESULT 2: "+bd2.toString());
RESULT 1: 13.300000000000000710542735760100185871124267578125
RESULT 2: 13.3
あな状況成果1という希望?知っているJava1.5に変更 toString()
方法がこの目的の結果?
もっと BigDecimal
は doubleValue()
などが、図書館にとっhelpfullyを採用 toString()
やまだひさしをはじめとする変化:-(
ございます!
解決
でも、 API はこの明らかに矛盾のコンストラクタ BigDecimal(double val)
:
このコンストラクタの結果は予想外である可能性がある。可能性のある そのとき BigDecimal(0.1)Javaを作成し BigDecimalが正確に一致 0.1(スケールなしの値の1のスケール1)ですが、実際に等しい へ 0.1000000000000000055511151231257827021181583404541015625.これは、0.1 できません 正確に表現としてダブル (または、 それは、バイナリの割合 の有限な長さ。これにより、価値 それに渡された コンストラクタは等しい 0.1.
文字列のコンストラクタでは、一方は完全に予測可能である。書面に新しいBigDecimal("0.1")の作成 BigDecimalが正確に一致 0.1という。そのため、 いうことをお勧めの 文字列コンストラクタを使用する 好みです。
きのダブルが必要源として使用されるためのBigDecimal, ることがあり このコンストラクタにより正確に 変換;なされているので、このよう 結果として変換したダブル 文字列を使用 ダブル。toString(double)メソッド そのBigDecimal(String) コンストラクタです。その結果、 使用 静valueOf(double)メ.
モラルのストーリー:の痛みよう自ら招いた危機なのだけを使用 new BigDecimal(String val)
または BigDecimal.valueOf(double val)
な=)
他のヒント
あなたの問題は、それが内部的にバイナリ画分を使用しているため、正確に13.3を表現することはできませんBigDecimal
、とDouble
とは何の関係もあり、すべてのものを持っていません。
だからあなたのエラーは非常に最初の行で導入されます。 String.valueOf()
はかなり運によって、所望のコンテンツを持っているために第2の1の原因となるいくつかの魚の丸めを行いつつ、第1 <=>は、単に、それを保存します。
あなたは浮動小数点値が( IEEE 754-1985実装されているかについて自分自身を通知する場合があります)。そして突然、すべてがクリスタルクリアになります。
このはBigDecimal
の故障ではありません - それはdouble
のせいです。 d
正確String.valueOf
の正確の値を表しています。 <=>わずか数桁までの結果を示している。
double
、float
)で表されるフラクションを正確にそれらの型に格納することができない。
Double d = 13.3;
BigDecimal bdNotOk = new BigDecimal(d);
System.out.println("not ok: " + bdNotOk.toString());
BigDecimal bdNotOk2 = new BigDecimal(13.3);
System.out.println("not ok2: " + bdNotOk2.toString());
double x = 13.3;
BigDecimal ok = BigDecimal.valueOf(x);
System.out.println("ok: " + ok.toString());
double y = 13.3;
// pretty lame, constructor's behavior is different from valueOf static method
BigDecimal bdNotOk3 = new BigDecimal(y);
System.out.println("not ok3: " + bdNotOk3.toString());
BigDecimal ok2 = new BigDecimal("13.3");
System.out.println("ok2: " + ok2.toString());
Double e = 0.0;
for(int i = 0; i < 10; ++i) e = e + 0.1; // some fractions cannot be accurately represented with binary
System.out.println("not ok4: " + e.toString()); // should be 1
BigDecimal notOk5 = BigDecimal.valueOf(e);
System.out.println("not ok5: " + notOk5.toString()); // should be 1
/*
* here are some fractions that can be represented exactly in binary:
* 0.5 = 0.1 = 1 / 2
* 0.25 = 0.01 = 1 / 4
* 0.75 = 0.11 = 3 / 4
* 0.125 = 0.001 = 1 / 8
*/
出力:
not ok: 13.300000000000000710542735760100185871124267578125
not ok2: 13.300000000000000710542735760100185871124267578125
ok: 13.3
not ok3: 13.300000000000000710542735760100185871124267578125
ok2: 13.3
not ok4: 0.9999999999999999
not ok5: 0.9999999999999999
ただ、使用の BigDecimal.valueOf(d)
または new BigDecimal(s)
の。