8

地球上でこれらの「同じ」式が異なる値を返す理由を誰か説明できますか?

(new BigDecimal(String.valueOf(131.7d))).multiply(new BigDecimal(String.valueOf(0.95d))).doubleValue() = 125.115

(new BigDecimal(               131.7d )).multiply(new BigDecimal(               0.95d )).doubleValue() = 125.11499999999998

BigDecimal の違いは何ですか?

4

2 に答える 2

6

APIドキュメントを見ると:

BigDecimal(double val)
          Translates a double into a BigDecimal which is the exact decimal representation of the double's binary floating-point value.

BigDecimal(String val)
          Translates the string representation of a BigDecimal into a BigDecimal.

これらは実際には同じものではありません。コンストラクターでは、double浮動小数点数を使用しています (これは本質的に不正確です)。Stringコンストラクターでは、指定した正確な値を取得し、浮動小数点変換を行いませんしたがって、これは実際には、上記のコンストラクターが「同じ」式ではないことを意味します

于 2013-03-28T15:25:51.593 に答える
5

API ドキュメントを読むと、値をフォーマットするためにString.valueOf(dobule)使用されていることがわかります。Double.toString(double)明らかではないかもしれませんがDouble.toString(double)、文字列としてフォーマットする前に値を丸めます:

m または a の小数部分は何桁で表示する必要がありますか? 小数部分を表すには少なくとも 1 桁が必要であり、それを超える桁数は、引数の値を double 型の隣接する値と一意に区別するために必要な数だけです。つまり、x が、有限の非ゼロ引数 d に対してこのメ​​ソッドによって生成された 10 進数表現によって表される正確な数学的値であるとします。この場合、d は x に最も近い double 値でなければなりません。または、2 つの double 値が x に等しく近い場合、d はそれらの 1 つでなければならず、d の仮数の最下位ビットは 0 でなければなりません。

この結果String.valueOf(131.7d)、引数の正確な値が 131.69999999999998863131622783839702606201171875 であっても、文字列 "131.7" が返されます。これは、2 進分数 (float や double で使用される) を使用して 10 進分数を常に正確に表現できるとは限らないためです。

したがって、newnew BigDecimal(String.valueOf(131.7))は正確な値 131.7 を持つ BigDecimal を作成します。new BigDecimal(131.7)正確な値 131.69999999999998863131622783839702606201171875 を持つ BigDecimal を作成します。

于 2013-03-28T15:40:15.083 に答える