Java で金額を表すには、BigDecimal が推奨されるベスト プラクティスであることを理解しています。あなたは何を使うのですか?代わりに使用したいより良いライブラリはありますか?
14 に答える
BigDecimal
はるばる。通貨で現金の価値をカプセル化する独自のクラスCash
またはクラスを作成する人がいると聞いたことがありますが、皮膚の下では、おそらく丸めを使用してまだです。Money
BigDecimal
BigDecimal.ROUND_HALF_EVEN
編集: Don が彼の回答で言及しているように、 timeandmoneyのようなオープンソース プロジェクトがあり、開発者が車輪を再発明するのを防ごうとしていることに拍手を送りますが、プレアルファ ライブラリを使用するのに十分な自信がありません。それを本番環境で。その上、ボンネットの下を掘り下げると、彼らも使用しているBigDecimal
ことがわかります。
JodaMoney ( http://www.joda.org/joda-money/ ) について知ることは、検索エンジンでここにたどり着いた人々にとって有益です。
私はここで自分の意見を述べているわけではありませんが、BigDecimal に対しては、誰かが捨てるべきであるという非常に良い議論があります。
http://lemnik.wordpress.com/2011/03/25/bigdecimal-and-your-money/
以前に出くわした便利なライブラリはJoda-Moneyライブラリです。その実装の 1 つは、実際に BigDecimal に基づいています。通貨のISO-4217仕様に基づいており、カスタマイズされた通貨リスト (CVS 経由でロード) をサポートできます。
このライブラリには少数のファイルがあり、変更が必要な場合にすばやく確認できます。Joda-Money は、Apache 2.0 ライセンスの下で公開されています。
ドルとセントだけを使用している場合は、long (小数点以下 2 桁のオフセット) を使用します。詳細が必要な場合は、大きな 10 進数を使用することをお勧めします。
いずれにせよ、私はおそらくクラスを拡張して、正しい形式を使用する .toString() を持ち、他のメソッドを配置する場所として使用します (長い間、小数がそうでない場合、乗算と除算は失敗します)調整していません)
また、独自のクラスとインターフェースを使用する場合は、実装を自由に置き換えることができます。
BigDecimal
または別の固定小数点表現は、一般的にお金に必要なものです。
浮動小数点 ( Double
、Float
) 表現と計算は不正確であり、誤った結果につながります。
時間とお金を扱うときはとても注意しなければなりません。
お金を使って仕事をしているときは、フロートやダブルを絶対に使わないことをみんなに知ってもらいたいと思います。
しかし、BigDecimalについてはよくわかりません。
ほとんどの場合、intまたはlongでセントを追跡するだけで問題ありません。このようにして、小数点以下の桁を処理することはありません。
印刷するときにのみドルを表示します。常に整数を使用して内部セントで作業します。分割する必要がある場合、またはMath.abs()を使用する必要がある場合、これは注意が必要な場合があります。
ただし、0.5セント、さらには100分の1セントでもかまいません。これを行うための良い方法がわかりません。あなたは1000分の1セントを処理し、長いものを使用する必要があるかもしれません。または多分あなたはBigDecimalを使用することを余儀なくされるでしょう
私はこれについてもっと多くのことを読みますが、お金を表すためにフロートまたはダブルを使用することについて話し始めるすべての人を無視します。彼らはただトラブルを求めているだけです。
私のアドバイスは完全ではないと感じていますので、もっと入れてください。あなたは危険なタイプを扱っています!
より良いライブラリtimeandmoneyがあります。IMO、これら2つの概念を表すためにJDKが提供するライブラリよりもはるかに優れています。
Money クラスを作成する方法です。下で BigDecimal(または int) を使用します。次に、Currency クラスを使用して丸め規則を定義します。
残念ながら、Java のオーバーロード演算子がないと、このような基本型を作成するのは非常に不快になります。
ねえ、これは BigDecimal に関する非常に興味深い記事で、double の代わりに使用されることがある理由を説明する例です。BigDecimal チュートリアル.
間違いなく BigDecimal ではありません。四捨五入と表示には、心配しなければならない特別なルールがたくさんあります。
Martin Fowler は、通貨金額を表す専用のMoneyクラスの実装を推奨しており、通貨換算のルールも実装しています。
最終的に通貨値を表示する場合は、DecimalFormat クラスを使用できます。ローカリゼーションのサポートを提供し、かなり拡張可能です。
上記の誰かと同じように、通貨も持つ Money クラスに BigDecimal をカプセル化します。重要なことは、特に異なる通貨を扱う場合は、非常に多くの単体テストを行うことです。また、次のようなテストを記述できるように、文字列または同じことを行うファクトリ メソッドを受け取る便利なコンストラクターを追加することをお勧めします。
assertEquals(Money.create("100.0 USD").add("10 GBP"),Money.create("116 USD"));
関連する制約と詳細が常に存在します。次の記事で概説されている微妙な問題を理解するのに十分な経験がない人は、実際の金融データを扱う前に真剣に再考する必要があります。
http://lemnik.wordpress.com/2011/03/25/bigdecimal-and-your-money
BigDecimal が唯一の正しい表現でも、パズルの唯一のピースでもありません。特定の条件下では、整数として格納されたセントに基づく Money クラスを使用するだけで十分であり、BigDecimal よりもはるかに高速です。はい、それはドルを通貨として使用し、金額を制限することを意味しますが、そのような制約は多くのユースケースで完全に受け入れられ、とにかくすべての通貨には丸めとサブデノミネーションの特別なケースがあるため、「普遍的な」ソリューションはありません.