2012-04-07 2 views
1
public static void Main() 
{ 
    Dictionary<string, double> values = new Dictionary<string, double>(); 
    values.Add("a", 0.002); 
    values.Add("b", 0.003); 
    values.Add("c", 0.012); 

    // Summing iteratively. 
    double v1 = 615.0; 
    foreach (KeyValuePair<string, double> kp in values) 
    { 
     v1 += kp.Value; 
    } 

    Console.WriteLine(v1); 

    // Summing using the Sum method. 
    double v2 = 615.0; 
    v2 += values.Values.Sum(); 

    Console.WriteLine(v2); 

    Console.ReadLine(); 
} 

私はデバッガでV1の値を見てみると、それは615.01699999999994の値を与えるが、v2のために、それは615.017の値を与えます。なんらかの理由でSumメソッドは正確な結果を返しますが、反復して加算するのではありません。 (私は2つの値を印刷するときは同じですが、これはWriteLineメソッドの四捨五入によるものと推測しています)。C#ダブル加え - 奇妙な行動

何が起こっているのですか?

+0

。 –

+2

浮動小数点は整数ではありませんか?私はあなたがそこに良い答えを見つけるだろうと思うので、このトピックを見て:http://stackoverflow.com/q/803225/1243316。 –

+1

@TheBossは同じ効果を参照してください。double d1 = 615.0 +(0.002 + 0.003 + 0.012); double d2 = 615.0 + 0.002 + 0.003 + 0.012; ' –

答えて

5

浮動小数点数の計算は本質的に100%正確ではなく、エラーが発生します。異なる数字を一緒に追加する順序は、浮動小数点エラーの程度に影響を与えます。これらの計算が完全に正確であることが重要な場合は、2倍ではなく10進を使用する必要があります。

これは、Sumと手動でデータを合計することとは関係ありません。最初に、あなたが行くごとに各数字を615に追加します.2番目にはすべての数字を互いに加算します。を次にに追加します。同じデータを追加する順序が異なります。どちらの方法を使用するかに応じて、多かれ少なかれエラーが発生する可能性があります。

+0

浮動小数点誤差が最小になるように合計する必要がある順序を知る方法はありますか?残念ながら、小数点の型も不正確です。上記の例ではなく、私が作成しているプログラムのためです。確かに不正確ではありませんが、Sumメソッドほど正確ではありません。 – TheBoss

+3

@ TheBoss:*少なくとも*エラーが出るためにどのような順序で合計する必要があるかを知る方法はありますか? **はい。**計算量が多く、エラー範囲を見積もるか最小限に抑える必要がある場合は、数値的方法で学部レベルのコースを受講するか、そのようなコースのテキストブックを入手することをおすすめしますそれを勉強しています。親指の大まかなルールとして、**最初に一緒に小さなものを追加**。それは最小化されたエラーを保証するものではありませんが、最初の近似としては良いです。 –

+0

小数は同様に「不正確」です。浮動小数点と小数はそれぞれ、特定のタイプのタスクに適していますが、どちらの精度も多少正確です。 – phoog

0

double/floatの問題点は、内部的に1000110.10101001という2進数であるため、おおよその値の表現に過ぎません。

読むジョンスキートの説明:Difference between decimal, float and double in .NET?それはあなたが二重の代わりに、小数点の使用に関係しています

+0

小数点および整数は、内部的に1と0で表される2進数です。基本的な違いは、小数点は小数点以下の桁数を表すために基数10のシステムを使用し、浮動小数点数は2を使用することです。 – phoog