質問
BigDecimalは、Javaで金銭的価値を表現するためのベストプラクティスとして推奨されていることを理解しています。あなたは何を使うのですか?代わりに使用したいライブラリがありますか?
解決
BigDecimal
までずっと。一部の人々は、通貨で現金価値をカプセル化する独自の Cash
または Money
クラスを作成することを聞いたことがありますが、スキンの下では依然として BigDecimal
、おそらく BigDecimal.ROUND_HALF_EVEN
丸め。
編集:ドンが回答で言及しているとおり a>、 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ライセンスの下で公開されています。
ドルとセントを使用している場合は、ロング(小数点以下2桁のオフセット)を使用します。さらに詳細が必要な場合は、大きな10進数を使用することをお勧めします。
どちらにしても、おそらく正しいフォーマットを使用する.toString()を持ち、出てくるかもしれない他のメソッドを置く場所としてクラスを拡張します(長い間、乗算と除算はうまくいかないでしょう小数は調整されません)
また、独自のクラスとインターフェースを定義する場合は、実装を自由に置き換えることができます。
BigDecimal
または別の固定小数点表現は、一般的にお金のために必要なものです。
浮動小数点( Double
、 Float
)の表現と計算は不正確であり、誤った結果につながります。
時間とお金を扱うときは注意が必要です。
お金を使って作業しているときは、フロートやダブルを絶対に使用しないでください。
しかし、BigDecimalについては確信がありません。
ほとんどの場合、intまたはlongでセントを追跡するだけで問題ありません。この方法では、小数点以下の桁を扱うことはありません。
印刷時にはドルのみが表示されます。常に整数を使用して内部セントで動作します。分割する必要がある場合やMath.abs()を使用する必要がある場合、これは難しい場合があります。
ただし、0.5セント、または100分の1セントでもかまいません。私はこれを行うには良い方法がわからない。 1000分の1セントを処理し、長いものを使用する必要があるかもしれません。または、BigDecimalの使用を余儀なくされるでしょう
これについてはもっと読みますが、お金を表すためにfloatまたはdoubleを使用することについて話し始める人は皆無視します。彼らはトラブルを求めているだけです。
私のアドバイスは完了していないように感じます。危険なタイプを扱っています!
Moneyクラスを作成する方法があります。 BigDecimal(またはint)を使用します。次に、通貨クラスを使用して丸め規則を定義します。
残念ながら、演算子にJavaをオーバーロードしないと、そのような基本型を作成するのは非常に不快になります。
より良いライブラリ、 timeandmoney があります。 IMO、これら2つの概念を表すためにJDKが提供するライブラリよりもはるかに優れています。
明らかにBigDecimalではありません。丸めと表示には特別なルールがたくさんあるので、心配する必要があります。
Martin Fowlerは、通貨額を表すために専用の Money クラスの実装を推奨しています。通貨換算のルールも実装しています。
ねえ、これはBigDecimalに関する非常に興味深い記事であり、なぜdoubleの代わりに使用されるのかを説明する例です。 BigDecimalチュートリアル。
最終的に通貨値を表示するときに、DecimalFormatクラスを使用できます。ローカライズのサポートを提供し、非常に拡張可能です。
私はBigDecimalをMoneyクラスにカプセル化します。これは、上記の誰かと同じように通貨も持っています。重要なことは、特に異なる通貨で作業している場合は、極端な量の単体テストを行うことです。また、文字列を受け取る便利なコンストラクターまたは同じことを行うファクトリーメソッドを追加して、次のようなテストを作成できるようにすることをお勧めします。
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よりもはるかに高速です。はい、これは通貨としてドルを使用し、金額を制限することを意味しますが、そのような制約は多くのユースケースに完全に受け入れられ、すべての通貨にはとにかく丸めおよび小額の特別なケースがあるため、「ユニバーサル」はありませんソリューション。