2009-05-16 22 views
0

コードがありますが、わかりません。私は精度が非常に重要なアプリケーションを開発しています。 .NETにとって重要ではないのはなぜですか?知りません。倍精度

double value = 3.5; 
MessageBox.Show((value + 1 * Math.Pow(10, -20)).ToString()); 

が、メッセージボックスを示しています。3.5 、私を助けていただき、ありがとうございます。

+0

http://stackoverflow.com/questions/566958/double-precision-problems-on-c-net –

+0

正確に3.50000000000000000001に等しい 'double'値はありません。その数に最も近い倍数は3.5です。 –

答えて

1

精度を持つことはできますが、それ以外に何をしたいかによって異なります。あなたがコンソールアプリケーションで次のように置く場合:

double a = 1e-20; 
Console.WriteLine(" a = {0}", a); 
Console.WriteLine("1+a = {0}", 1+a); 

decimal b = 1e-20M; 
Console.WriteLine(" b = {0}", b); 
Console.WriteLine("1+b = {0}", 1+b); 

あなたは

a = 1E-20 
1+a = 1 
b = 0,00000000000000000001 
1+b = 1,00000000000000000001 

を得る。しかしPow関数は、Mathクラスのほぼすべてのもののように、唯一のダブルスを取ることに注意します:

double Pow(double x, double y); 

10進数の正弦を取ることはできません(それ以外はdoubleに変換します)

this questionも参照してください。

1

または、ダブルではなくDecimalタイプを使用してください。

+0

しかし、小数点にMath.Pow()を使用することはできません。 –

+1

10^-20は簡単に定数として与えることができます。ここでMath.Pow()を呼び出す必要はありません。 – Joey

+0

ええ、あなたは正しいですが、私はちょうど私の問題を示したかったのです。 –

2

Doubleの精度は15桁(内部17桁)です。 Math.Powで計算した値は正しいですが、valueに加算すると小さすぎて違いがありません。

編集:
Decimalはその精度を処理できますが、計算は処理できません。あなたは精度が、あなたが計算を行う必要があることをしたい場合は、それらを一緒に追加する前にDecimalに各値を変換:

double value = 3.5; 
double small = Math.Pow(10, -20); 

Decimal result = (Decimal)value + (Decimal)small; 

MessageBox.Show(result.ToString()); 
+0

この番号はどうすればよいですか? –

+0

Decimalはその精度を持ちますが、計算をdoubleとして実行してから、それらを加算する前にそれぞれをDecimalに変換する必要があります。上記の私の編集を参照してください。 – Guffa

0

倍精度は、15〜16個の数字を保持できることを意味します。 3.5 + 1e-20 = 21桁。倍精度で表すことはできません。小数点のような別の型を使用できます。

+0

しかし、浮動小数点数の後にいくつの数値を入れることができますか? –

+0

合計15〜16桁。浮動小数点は、これらの数字の前、後、またはその間にあります。 – Kcats

2

精度が非常に重要な場合は、浮動小数点の制限に注意する必要があります。良いリファレンスはDavid Goldberg's "What Every Computer Scientist Should Know About Floating-Point Arithmetic"です。

浮動小数点では精度が十分ではなく、小数点以下の型で処理する必要があります。しかし、これらは常に浮動小数点よりもはるかに遅く、精度と速度のトレードオフです。

+0

良い記事ですが、非数学者が読むのは少し難しいです。これは、コードサルの読み方がやや簡単です:http://floating-point-gui.de/ –