質問

私は常にc#でdouble型の変数はお金に適さないと言っています。すべての奇妙なことが起こる可能性があります。しかし、これらの問題のいくつかを示すための例を作成することはできません。誰でもそのような例を提供できますか?

(編集;この投稿は元々C#でタグ付けされていました;一部の返信は decimal の特定の詳細を参照しているため、 System.Decimal )。

(編集2:特定のC#コードを要求していたため、これは言語に依存しないとは思わない)

役に立ちましたか?

解決

非常に不適切です。 10進数を使用します。

double x = 3.65, y = 0.05, z = 3.7;
Console.WriteLine((x + y) == z); // false

(Jonのページこちらの例-推奨読書;-p)

他のヒント

丸めにより事実上奇妙なエラーが発生します。さらに、正確な値との比較は非常に注意が必要です。通常、実際の値が「近い」かどうかを確認するには、何らかのイプシロンを適用する必要があります。特定のもの。

具体例を次に示します。

using System;

class Test
{
    static void Main()
    {
        double x = 0.1;
        double y = x + x + x;
        Console.WriteLine(y == 0.3); // Prints False
    }
}

はい、それは不適切です。

doubleの有効数字が約17個あることを正しく覚えていれば、通常、丸め誤差は小数点のはるか後ろで発生します。ほとんどの金融ソフトウェアは小数点以下4桁を使用し、13桁の小数点を使用できるため、1回の操作で使用できる最大数は米国の国債よりもはるかに多くなっています。ただし、丸め誤差は時間の経過とともに増加します。ソフトウェアが長時間実行されると、最終的にセントを失います。特定の操作はこれを悪化させます。たとえば、大量を少量に追加すると、精度が大幅に低下します。

金銭操作には固定小数点データ型が必要です。あちこちでセントを失ってもほとんどの人は気にしませんが、会計士はほとんどの人が好きではありません。

編集
このサイトによると、 http://msdn.microsoft.com/en-us/library /678hzkk9.aspx ダブルには実際には17ではなく15から16桁の有効数字があります。

@Jon Skeet 10進数は、精度が高く、有効桁数が28または29であるため、doubleよりも適しています。つまり、累積丸め誤差が大きくなる可能性が低くなります。 Boojumの言及のような固定小数点データ型(セントや100分の1セントを表す整数)は、実際により適しています。

decimal は10の倍数のスケーリング係数を使用するため、0.1などの数値は正確に表現できます。本質的に、decimal型はこれを1/10 ^ 1として表しますが、 double はこれを104857/2 ^ 20として表します(実際には really-big-numberのようになります) / 2 ^ 1023)。

A decimal は、有効桁数が最大28/29(0.1など)の任意のベース10値を正確に表すことができます。 double はできません。

私の理解では、ほとんどの金融システムは整数を使用して通貨を表します。つまり、すべてをセントでカウントします。

IEEE倍精度は、実際には-2 ^ 53から+ 2 ^ 53の範囲のすべての整数を正確に 表すことができます。 (Hacker's Delight、pg。262)加算、減算、乗算のみを使用し、すべてをこの範囲内の整数に保つと、精度が失われることはありません。ただし、除算やより複雑な操作には非常に注意してください。

何をしているのかわからないときにdoubleを使用するのは不適切です。

" double" 1/90セントの誤差で1兆ドルの金額を表すことができます。したがって、非常に正確な結果が得られます。火星に人を置き、彼を生き返らせるのにどれくらいの費用がかかりますか? doubleは問題ありません。

しかし、お金がある場合、特定の計算では特定の結果が得られ、他の結果は得られないという非常に具体的なルールがしばしばあります。 $ 98.135に非常に近い金額を計算する場合、結果が$ 98.14と$ 98.13のどちらであるかを決定するルールがあり、そのルールに従って 必要な結果を取得する必要があります。 。

お住まいの地域に応じて、64ビット整数を使用してセント、ペニー、コペック、または国の最小単位を表すことで、通常は正常に機能します。たとえば、セントを表す64ビットの符号付き整数は、最大92,223兆ドルの値を表すことができます。通常、32ビット整数は不適切です。

倍精度では常に丸め誤差は発生しません。「10進数」を使用してください。 .Netを使用している場合...

実際に浮動小数点 double は、適切な単位を選択する限り、金額を表すのに最適です。

http://www.idinews.com/moneyRep.html

をご覧ください。

固定小数点 long も同様です。どちらも8バイトを消費します。 10進数アイテムで消費される16バイトよりも確実に望ましいです。

何かが機能する(つまり、期待される正しい結果が得られる)かどうかは、投票または個人の好みの問題ではありません。テクニックは機能するか機能しないかのいずれかです。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top