2009-05-19 17 views
6

現在、Steve McConnellによるコード完成、特に浮動小数点数のページ295を読み込んでいます。印刷インクリメント0.1 in c#

iは、次のコードを実行する場合:

 double nominal = 1.0; 
     double sum = 0.0; 

     for (int i = 0; i < 10; i++) 
     { 
      sum += 0.1; 
      Console.WriteLine("sum: " + sum.ToString()); 
     } 

     if (equals(nominal,sum)) 
     { 
      Console.WriteLine("Numbers are the same"); 
     } 
     else 
     { 
      Console.WriteLine("Numbers are different"); 
     } 

をI印刷を得たアウトの 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 番号が異なる

どのように私はdidn '起こると思われる出力を得るか? 、すなわち:私はダブルから文字列への暗黙的な変換を行うと 0.1 0.2 0.30000000000000004 0.4 0.5 0.6 0.7 0.79999999999999999 0.89999999999999999 0.99999999999999999 数字は

異なるC#丸め番号ですか?私はアプリケーションをデバッグし、forループをステップ実行すると、終端ではない繰り返しの10進数を見ることができるので、そうだと思います。どう思いますか?私は間違っていますか?

答えて

12

double.ToString()は、精度が指定されていない場合、デフォルトで小数点以下15桁までの一般形式を使用します。だから、あなたはあなたが見ているものを見ているのですが、少し丸めています。たとえば、質問で指定した0.89999999999999999は小数点以下17桁です。 sum.ToString("g17")を実行すると、実際には番号全体が表示されます。

は、.NETの標準の数値書式指定文字列と、ここで彼らのデフォルトの精度を見つけることができます:それはあるhttp://msdn.microsoft.com/en-us/library/dwhawy9k(VS.80).aspx

+0

ああありがとうございます。 私はあなたが与えた出力で非常に正確だったはずです。私が0.79999999999999999のような長い10進数を与えたとき、私は使用していた桁数に注意を払わなかった。 – burnt1ce

2

は、ToStringメソッドのデフォルトの動作であるが。デバッガで合計を見れば、あなたはToStringメソッドを経由することなく、あなたの値を示しており、これを取得:

0.0 
0.1 
0.2 
0.30000000000000004 
0.4 
0.5 
0.6 
0.7 
0.79999999999999993 
0.89999999999999991 

は、あなたが期待するよう根本的な行動であることを示します。

HTH

2

短い答えは:それは、浮動小数点ていますので、何にもカウントされませんが、それは(「右」の適切な値のために)右のもの!長い回答者は、浮動小数点の動作方法と浮動小数点の使用方法を理解することです。 IIRC GNU printf(と私が想定している他の)特殊なケースは "本当に素敵な基数10に近い"。