web-dev-qa-db-ja.com

10進vsダブル! - いつどれを使うべきですか?

私は人々がC#でdoubleを使っているのを見続けています。倍精度は時々正確さを失うことを私はどこかで読んだことを知っています。私の質問は、いつdoubleを使用すべきで、いつ10進型を使用すべきかということです。どのタイプがお金の計算に適していますか? (つまり1億ドル以上)

817
Soni Ali

お金のために、 常に decimal。それが作られた理由です。

数が正しく足し合わなければならないか、バランスをとる必要がある場合は、10進数を使用してください。これには、財務上の保存、計算、スコア、その他の数字が含まれます。

数値の正確な値が重要でない場合は、速度を上げるためにdoubleを使用してください。これには、グラフィック、物理学、または「有効桁数」がすでに存在する他の物理科学計算が含まれます。

964
David

私の質問は、いつdoubleを使用し、decimal型を使用する必要があるかです。

decimalは、10 ^(+/- 28)の範囲の値を操作する場合、および基本10表現に基づく動作についての期待がある場合-基本的にはお金です。

doubleが必要な場合relativeの精度(つまり、大きな値の末尾の桁の精度を失うことは問題ではありません)大幅に異なる大きさで-doubleは10 ^(+/- 300)以上をカバーします。科学的な計算がここでの最良の例です。

どのタイプがお金の計算に適していますか?

decimal、decimaldecimal

代替物を受け入れない。

最も重要な要因は、バイナリ分数として実装されているdoubleは、多くのdecimal分数(0.1など)を正確に表すことができずすべてであり、全体の桁数は64であるため小さいdecimalのビット幅と128ビット。最後に、金融アプリケーションは多くの場合、特定の 丸めモード (法律で義務付けられている場合もある)に従う必要があります。 decimalこれらをサポート ; doubleはサポートしていません。

170

System.Single / float - 7桁
System.Double / double - 15〜16桁
System.Decimal / decimal - 28から29の有効数字

私が間違ったタイプを使用することによって私が刺された方法は(かなり前の数年)たくさんあります。

  • £520,532.52 - 8桁
  • 1,323,523.12ポンド - 9桁

あなたはフロートで100万で足りなくなりました。

15桁の金銭的価値:

  • £1,234,567,890,123.45

ダブルで9兆。しかし、除算と比較ではそれはもっと複雑です(私は間違いなく浮動小数点数と無理数の専門家ではありません - Marcの要点を参照してください )。小数点と倍精度を混在させると問題が発生します。

浮動小数点数を使用する数学演算または比較演算では、10進数を使用すると同じ結果にならない可能性があります。これは、浮動小数点数が10進数に正確に近似しない​​場合があるためです。

10進数ではなく倍精度記号を使うべきなのはいつですか?いくつかの類似した詳細な回答があります。

double通貨アプリケーション用の代わりにdecimalを使用するのは、微最適化です - これが私が見る最も簡単な方法です。

37
Chris S

10進数は正確な値です。 Doubleは概算値です。

USD: $12,345.67 USD (Decimal)
CAD: $13,617.27 (Decimal)
Exchange Rate: 1.102932 (Double)
34
Ian Boyd

お金のために:decimal。もう少しメモリがかかりますが、doubleのように丸めの問題はありません。

26

間違いなく あなたのお金の計算に整数型を使う。一見すると浮動小数点型が適切であるように見えるかもしれないので、これは十分に強調することはできません。

これがPythonコードの例です。

>>> amount = float(100.00) # one hundred dollars
>>> print amount
100.0
>>> new_amount = amount + 1
>>> print new_amount
101.0
>>> print new_amount - amount
>>> 1.0

かなり普通に見えます。

10 ^ 20ジンバブエドルでこれをもう一度試してください

>>> amount = float(1e20)
>>> print amount
1e+20
>>> new_amount = amount + 1
>>> print new_amount
1e+20
>>> print new_amount-amount
0.0

ご覧のとおり、ドルは消えました。

整数型を使用している場合は、うまく機能します。

>>> amount = int(1e20)
>>> print amount
100000000000000000000
>>> new_amount = amount + 1
>>> print new_amount
100000000000000000001
>>> print new_amount - amount
1
8

ビット幅以外の主な違いは、10進数の指数が10で倍精度の2が2であることです。

http://software-product-development.blogspot.com/2008/07/net-double-vs-decimal.html

5
Honzajscz