285

の代わりにdouble(または)を使用する利点を 3 つ挙げることができます。floatdecimal

  1. メモリ使用量が少なくなります。
  2. 浮動小数点演算がプロセッサでネイティブにサポートされているため、高速です。
  3. より広い範囲の数値を表すことができます。

しかし、これらの利点は、モデリング ソフトウェアに見られるような計算集約型の操作にのみ適用されるようです。もちろん、財務計算など、精度が必要な場合は double を使用しないでください。では、「通常の」アプリケーションの代わりにdouble(または) を選択する実用的な理由はありますか?floatdecimal

追加するために編集: すべてのすばらしい応答に感謝します, 私はそれらから学びました.

もう 1 つの質問: double の方が実数をより正確に表すことができると主張する人が何人かいます。宣言されたとき、それらは通常、より正確に表現されていると思います。しかし、浮動小数点演算を実行すると精度が (場合によっては大幅に) 低下する可能性があるというのは本当ですか?

4

12 に答える 12

316

メリットをうまくまとめられていると思います。ただし、1 つのポイントが不足しています。この型は、 10decimal進数を表す場合にのみ正確です (たとえば、通貨/財務計算で使用されるもの)。一般に、この 型は少なくとも同等の精度 (間違っていたら訂正してください) を提供し、任意の実数に対して明らかに高速になります。簡単な結論は次のとおりです。どちらを使用するかを検討するときは、提供される精度が必要でない限り、常に使用してください。doubledoublebase 10decimal

編集:

演算後の浮動小数点数の精度の低下に関する追加の質問に関しては、これはもう少し微妙な問題です。実際、精度 (ここでは正確さという意味でこの用語を同じ意味で使用します) は、各操作が実行されるたびに着実に低下します。これには、次の 2 つの理由があります。

  1. 特定の数値 (最も明らかに 10 進数) が浮動小数点形式で正確に表現できないという事実
  2. 手で計算を行っているかのように、丸め誤差が発生します。ただし、これらのエラーが十分に考慮に値するほど重要であるかどうかは、コンテキスト (実行している操作の数) に大きく依存します。

どのような場合でも、理論的には等しいはずの 2 つの浮動小数点数を比較したい場合 (ただし、異なる計算を使用して得られたもの)、ある程度の許容範囲を許容する必要があります (どの程度変化するか、通常は非常に小さい)。 .

精度のエラーが発生する可能性がある特定のケースの詳細な概要については、ウィキペディアの記事の「精度」セクションを参照してください。最後に、マシン レベルでの浮動小数点数/演算について深く掘り下げた (そして数学的) 議論が必要な場合は、よく引用される記事What Every Computer Scientist Should Know About Floating-Point Arithmeticを読んでみてください。

于 2009-04-29T16:46:19.633 に答える
62

浮動小数点型を使用する利点に注目しているようです。私は常に 10 進数を考慮して設計する傾向があり、10 進数の演算がボトルネックやスローダウンを引き起こしているかどうかをプロファイラーに知らせてくれます。そのような場合、double または float に「ダウン キャスト」しますが、これは内部的にのみ行い、実行される数学演算の有効桁数を制限することで精度の低下を慎重に管理しようとします。

一般に、値が一時的な (再利用されない) 場合は、浮動小数点型を安全に使用できます。浮動小数点型に関する実際の問題は、次の 3 つのシナリオです。

  1. 浮動小数点値を集計しています (この場合、精度エラーが悪化します)
  2. 浮動小数点値に基づいて値を作成します (再帰アルゴリズムなど)。
  3. 有効桁数が非常に多い計算をしている (例: 123456789.1 * .000000000000000987654321)

編集

C# 10 進数に関するリファレンス ドキュメントによると、次のようになります。

decimalキーワードは、128 ビットのデータ型を示します。浮動小数点型と比較して、10 進数型は精度が高く、範囲が狭いため、金融および通貨の計算に適しています。

したがって、私の上記の声明を明確にするために:

私は常に 10 進数を考慮して設計する傾向があり、10 進数の演算がボトルネックやスローダウンを引き起こしているかどうかをプロファイラーに知らせてくれます。

私は、小数が有利な業界でしか働いたことがありません。物理演算やグラフィック エンジンを扱っている場合は、浮動小数点型 (float または double) 用に設計する方がおそらくはるかに有益です。

Decimal は無限に正確ではありません (プリミティブ データ型で非整数に対して無限の精度を表すことは不可能です) が、double よりもはるかに正確です。

  • 10 進数 = 28 ~ 29 桁の有効数字
  • double = 有効数字 15 ~ 16 桁
  • float = 有効数字 7 桁

編集2

Konrad Rudolphのコメントに応えて、項目 1 (上記) は間違いなく正しいです。不正確さの集約は確かに複合的です。例については、次のコードを参照してください。

private const float THREE_FIFTHS = 3f / 5f;
private const int ONE_MILLION = 1000000;

public static void Main(string[] args)
{
    Console.WriteLine("Three Fifths: {0}", THREE_FIFTHS.ToString("F10"));
    float asSingle = 0f;
    double asDouble = 0d;
    decimal asDecimal = 0M;

    for (int i = 0; i < ONE_MILLION; i++)
    {
        asSingle += THREE_FIFTHS;
        asDouble += THREE_FIFTHS;
        asDecimal += (decimal) THREE_FIFTHS;
    }
    Console.WriteLine("Six Hundred Thousand: {0:F10}", THREE_FIFTHS * ONE_MILLION);
    Console.WriteLine("Single: {0}", asSingle.ToString("F10"));
    Console.WriteLine("Double: {0}", asDouble.ToString("F10"));
    Console.WriteLine("Decimal: {0}", asDecimal.ToString("F10"));
    Console.ReadLine();
}

これにより、次が出力されます。

Three Fifths: 0.6000000000
Six Hundred Thousand: 600000.0000000000
Single: 599093.4000000000
Double: 599999.9999886850
Decimal: 600000.0000000000

ご覧のように、同じソース定数から追加しているにもかかわらず、double の結果は精度が低く (おそらく正しく丸められます)、float ははるかに精度が低く、わずかに削減されています。有効数字2桁。

于 2009-04-29T16:44:37.437 に答える
26

他の人が示唆しているように、財務計算など、基数 10 の値には 10 進数を使用します。

ただし、一般に、任意の計算値に対して double の方が正確です。

たとえば、ポートフォリオの各ラインの重みを計算する場合は、結果がほぼ 100% になるように double を使用します。

次の例では、doubleResult は decimalResult よりも 1 に近いです。

// Add one third + one third + one third with decimal
decimal decimalValue = 1M / 3M;
decimal decimalResult = decimalValue + decimalValue + decimalValue;
// Add one third + one third + one third with double
double doubleValue = 1D / 3D;
double doubleResult = doubleValue + doubleValue + doubleValue;

もう一度ポートフォリオの例を見てみましょう:

  • ポートフォリオの各ラインの市場価値は金銭的価値であり、おそらく小数で表すのが最も適切でしょう。

  • ポートフォリオの各ラインの重み (= 市場価値 / SUM(市場価値)) は、通常、2 倍で表す方が適切です。

于 2009-04-29T17:26:43.390 に答える
6

精度が必要ない場合は double または float を使用します。たとえば、私が書いたプラットフォーマー ゲームでは、プレイヤーの速度を格納するために float を使用しました。画面に描画するために最終的に Int に丸められるため、明らかにここでは超精度は必要ありません。

于 2009-04-29T16:42:46.617 に答える
3

他の言語またはプラットフォームとのバイナリ相互運用が必要な場合は、標準化されている float または double を使用する必要がある場合があります。

于 2009-04-29T16:47:34.920 に答える
2

注: この投稿は、 http://csharpindepth.com/Articles/General/Decimal.aspxからの decimal 型の機能に関する情報と、それが何を意味するかについての私自身の解釈に基づいています。Double は通常の IEEE 倍精度であると仮定します。

注 2: この投稿の最小値と最大値は、数値の大きさを示しています。

「小数」の長所。

  • "decimal" は、(十分に短い) 小数として記述できる数値を正確に表すことができますが、double はできません。これは、計算を行う人間が与える結果と正確に一致することが重要な財務台帳などで重要です。
  • "decimal" の仮数は "double" よりもはるかに大きくなります。つまり、正規化された範囲内の値の場合、「10 進数」は倍精度よりもはるかに高い精度になります。

小数の短所

  • それははるかに遅くなります(ベンチマークはありませんが、少なくとも1桁はそれ以上だと思います)、10進数はハードウェアアクセラレーションの恩恵を受けず、算術演算は10の累乗による比較的高価な乗算/除算が必要になります(これは、2 の累乗による乗算と除算よりもはるかにコストがかかります) 加算/減算の前に指数を一致させ、乗算/除算後に指数を範囲に戻します。
  • decimal は double よりも早くオーバーフローします。decimal は、最大 ±2 96 -1の数値のみを表すことができます。比較すると、double はほぼ ±2 1024までの数値を表すことができます。
  • decimal の方が早くアンダーフローします。10 進数で表現できる最小の数値は ±10 -28です。比較すると、double は、下位数がサポートされている場合は2 -149 (約 10 -45 ) まで、サポートされていない場合は 2 -126 (約 10 -38 ) までの値を表すことができます。
  • decimal は double の 2 倍のメモリを消費します。

私の意見では、お金の仕事や、人間の計算を正確に一致させることが重要なその他の場合には、デフォルトで「decimal」を使用する必要があり、それ以外の場合は、デフォルトの選択肢として double を使用する必要があります。

于 2016-03-22T16:33:15.683 に答える
0

アプリケーションの機能のタイプを選択します。財務分析のように精度が必要な場合は、質問に答えました。ただし、アプリケーションが見積もりで解決できる場合は、ダブルで問題ありません。

あなたのアプリケーションは迅速な計算を必要としていますか、それとも彼はあなたに答えを与えるために世界中で常に時間を持っていますか? それは本当にアプリケーションの種類によって異なります。

グラフィックに飢えていますか?float または double で十分です。財務データ分析、惑星に衝突する隕石のような精度? それらには少し精度が必要です:)

于 2009-04-29T17:16:30.480 に答える
0

正確さよりもパフォーマンスを重視する場合は、浮動小数点を使用してください。

于 2009-04-29T16:56:59.187 に答える