web-dev-qa-db-ja.com

BigDecimal-newまたはvalueOfを使用します

ダブルdからBigDecimalオブジェクトを取得する2つの方法に出会いました。

1. new BigDecimal(d)
2. BigDecimal.valueOf(d)

どちらがより良いアプローチでしょうか? valueOfは新しいオブジェクトを作成しますか?

一般的に(BigDecimalだけでなく)、推奨されるものは-newまたはvalueOfですか?

ありがとう。

85
Manish Mulani

これらは2つの別個の質問です:「BigDecimalに何を使用すべきですか?」と「私は一般的に何をしますか?」

BigDecimalの場合:これらは同じことをしないため、少し注意が必要です。 BigDecimal.valueOf(double) を使用します canonical String representation of the doubleBigDecimalオブジェクトをインスタンス化するために渡される値。つまり、BigDecimalオブジェクトの値は、System.out.println(d)を実行したときに表示される値になります。

ただし、 new BigDecimal(d) を使用すると、BigDecimaldoubleをできるだけ正確に表現しようとします。これにより、通常は、必要以上に多くの桁が格納されます。厳密に言うと、valueOf()よりも正確ですが、直感的ではありません。

これについてはJavaDocに説明があります。

このコンストラクタの結果は、いくぶん予測不能です。 Javaでnew BigDecimal(0.1)を記述すると、0.1(スケールなしの値1、スケール1)に正確に等しいBigDecimalが作成されます。これは、実際には0.1000000000000000055511151231257827021181583404541015625に等しくなります。これは、0.1をdouble(または、そのため、有限長のバイナリ分数)として正確に表現できないためです。コンストラクターは、外観にかかわらず、0.1に正確には等しくありません。

一般に、結果が同じ場合(つまり、BigDecimalの場合ではなく、ほとんどの場合)、valueOf()は優先される:一般的な値のキャッシュを行うことができ( Integer.valueOf() を参照)、呼び出し側を変更せずにキャッシュ動作を変更することもできます。 newは、必要ではない場合でもalways新しい値をインスタンス化します(最良の例:new Boolean(true) vs. Boolean.valueOf(true))。

145
Joachim Sauer

BigDecimalオブジェクトを使用して通貨の値を保存する場合は、[〜#〜] not [〜#〜]に任意のdoubleを含めることを強くお勧めします計算のどこでも値。

別の回答で述べたように、二重値に関する既知の精度の問題があり、これらはあなたに大きな時間を悩ませるように戻ってきます。

それを超えたら、あなたの質問への答えは簡単です。 valueOfにはStringメソッドがないため、コンストラクターの引数としてString値を使用して、常にコンストラクターメソッドを使用します。

証明が必要な場合は、次を試してください。

BigDecimal bd1 = new BigDecimal(0.01);
BigDecimal bd2 = new BigDecimal("0.01");
System.out.println("bd1 = " + bd1);
System.out.println("bd2 = " + bd2);

次の出力が得られます。

bd1 = 0.01000000000000000020816681711721685132943093776702880859375
bd2 = 0.01

こちらもご覧ください 関連する質問

43
DuncanKinnear

基本的にvalueOf(double val)はこれを行います:

return new BigDecimal(Double.toString(val));

したがって->はい、新しいオブジェクトが作成されます:)。

一般的に、それはあなたのコーディングスタイルに依存すると思います。両方が同じ結果である場合、valueOfと「new」を混在させません。

4
DXTR66