絶対に sBigDecimal
を使用できず、使用したくないdouble
場合は、s を使用して固定小数点演算を行います(たとえば、各値がセント数を表すようにします)。これにより、18 桁の有効数字を表すことができます。 long
long
joda-moneyを使用すると思いますが、これは裏で使用BigDecimal
されます。
編集(上記は実際には質問に答えていないため):
免責事項: 正確さが重要な場合は、money を使用しないでくださいdouble
。しかし、投稿者は正確な正確さを必要とせず (これは、おそらく 10**-12 を超える不確実性が組み込まれている金融価格設定モデルに関するものと思われます)、パフォーマンスを重視しているようです。これが事実であると仮定すると、 a を使用することdouble
は許されます。
一般に、adouble
は小数を正確に表すことはできません。では、 a はどれほど不正確なのdouble
でしょうか? これには簡単な答えはありません。
Aは、数値を aに読み取ってから再度書き戻して、小数点以下 15 桁の精度を保持double
できるほど十分に数値を表すことができる場合があります。double
しかし、これは小数ではなく 2 進数であるため、正確に表すことはできません。これは、表現したい値であり、プラスまたはマイナスの誤差があります。不正確な s を含む多くの算術演算が実行されるdouble
と、最終的な結果の精度が 10 進数で 15 桁未満になるように、この誤差の量が時間の経過とともに増加する可能性があります。何個少ない?場合によります。
n
1000 の th ルートを取り、それ自体をn
何回も乗算する次の関数を考えてみましょう。
private static double errorDemo(int n) {
double r = Math.pow(1000.0, 1.0/n);
double result = 1.0;
for (int i = 0; i < n; i++) {
result *= r;
}
return 1000.0 - result;
}
結果は次のとおりです。
errorDemo( 10) = -7.958078640513122E-13
errorDemo( 31) = 9.094947017729282E-13
errorDemo( 100) = 3.410605131648481E-13
errorDemo( 310) = -1.4210854715202004E-11
errorDemo( 1000) = -1.6370904631912708E-11
errorDemo( 3100) = 1.1107204045401886E-10
errorDemo( 10000) = -1.2255441106390208E-10
errorDemo( 31000) = 1.3799308362649754E-9
errorDemo( 100000) = 4.00075350626139E-9
errorDemo( 310000) = -3.100740286754444E-8
errorDemo(1000000) = -9.706695891509298E-9
累積された不正確さのサイズは、中間ステップの数に正確に比例して増加しないことに注意してください (実際、単調に増加するわけではありません)。既知の一連の中間操作が与えられると、不正確さの確率分布を決定できます。これは操作が多いほど範囲が広くなりますが、正確な量は計算に入力される数値によって異なります。不確実性はそれ自体不確実です!
実行している計算の種類によっては、中間ステップの後で単位全体またはセント単位に丸めることで、このエラーを制御できる場合があります。double
(毎月複利で年利 6% の $100 を保有する銀行口座の場合を考えてみましょう。したがって、月あたりの利子は 0.5% です。3 か月目の利子が入金された後、残高を $ 101.50または $101.51 にしたいですか?)全体の単位数よりも分数単位 (つまり、セント) の方が簡単になりますが、そうする場合は、long
上で提案したように s を使用することもできます。
免責事項、繰り返しますが、浮動小数点エラーの累積により、double
s を使用して金額を計算すると、非常に面倒になる可能性があります。何年にもわたって叩きつけられたものを 10 進表現に使用するという弊害を経験してきた Java 開発者として言えば、double
お金に関する重要な計算には浮動小数点演算ではなく 10 進法を使用します。