web-dev-qa-db-ja.com

Java:現実の世界でDoubleではなくBigDecimalを使用する理由

現実の金銭的価値を扱う場合、Doubleの代わりにBigDecimalを使用することをお勧めしますが、「通常はそのように行われます」以外の説得力のある説明はありません。

この質問に光を当ててください。

50

これは精度の損失と呼ばれ、非常に大きな数または非常に小さな数を扱う場合に非常に顕著です。基数付きの10進数のバイナリ表現は、多くの場合、近似値であり、絶対値ではありません。バイナリの浮動小数点表現を読む必要がある理由を理解するため。ここにリンクがあります: http://en.wikipedia.org/wiki/IEEE_754-2008 。以下に簡単なデモを示します。
bc(任意精度の計算機言語)in precision = 10:

(1/3 + 1/12 + 1/8 + 1/30)= 0.6083333332
(1/3 + 1/12 + 1/8)= 0.541666666666666
(1/3 + 1/12)= 0.416666666666666

Javaダブル:
0.6083333333333333
0.5416666666666666
0.41666666666666663

Javaフロート:

0.60833335
0.5416667
0.4166667


あなたが銀行であり、毎日何千もの取引を担当している場合、たとえそれらが同一の口座との間ではなくても(あるいはそうであっても)、信頼できる番号を持っている必要があります。バイナリフロートは信頼性がありません-動作とその制限を理解していない限りではありません。

BigDecimalはdoubleよりも高い精度を格納できますが、通常これは必要ありません。さまざまな丸め戦略を含め、丸めがどのように実行されるかが明確になるため、実際に使用された理由。ほとんどの場合、doubleを使用して同じ結果を得ることができますが、必要なテクニックがわからない限り、BigDecimalがこれらの場合に行く方法です。

一般的な例はお金です。使用ケースの99%でBigDecimalの精度を必要とするほどお金が大きくならないとしても、BigDecimalを使用することがベストプラクティスと見なされることがよくあります。丸め処理の間違い。 doubleで丸めを処理できると確信していても、ヘルパーメソッドを使用して、徹底的にテストする丸めを実行することをお勧めします。

29
Peter Lawrey

これは主に精度の理由で行われます。 BigDecimalは、浮動小数点数を無制限の精度で保存します。あなたはそれをよく説明しているこのページを見ることができます。 http://blogs.Oracle.com/CoreJavaTechTips/entry/the_need_for_bigdecimal

1
Sai

BigDecimalを使用すると、Doubleよりもはるかに多くのデータを保存できるため、より正確になり、実世界でのより良い選択になります。

それはずっと遅くて長いですが、それは価値があります。

上司に不正確な情報を伝えたくないのではないでしょうか。

0
Jason

別のアイデア:longのセント数を追跡​​します。これはより単純で、BigDecimalの面倒な構文とパフォーマンスの低下を回避します。

丸め誤差のためにお金が消えると人々は非常にイライラするため、財務計算の精度は非常に重要です。これがdoubleがお金を扱うためのひどい選択である理由です。

0