この次の算術問題に遭遇しました。
しかし、結果は通常の演算とは異なります。
double d1 = 1.000001;
double d2 = 0.000001;
Console.WriteLine((d1-d2)==1.0);
この次の算術問題に遭遇しました。
しかし、結果は通常の演算とは異なります。
double d1 = 1.000001;
double d2 = 0.000001;
Console.WriteLine((d1-d2)==1.0);
Jon Skeet の Brainteasers ページで質問を見つけたと思いますか? 回答は、同じ Web サイトでここにリストされ、説明されています。
参考までに、そのページからコピーした回答を次に示します。
3) 愚かな算数
コンピュータは算数が得意なはずですよね。これが「False」と表示されるのはなぜですか?
double d1 = 1.000001; double d2 =
0.000001; Console.WriteLine((d1-d2)==1.0);
回答: ここにあるすべての値は、2 進浮動小数点として格納されます。While 1.0 can be stored exactly, 1.000001 is actually stored as 1.0000009999999999177333620536956004798412322998046875, and 0.000001 is actually stored as 0.000000999999999999999954748111825886258685613938723690807819366455078125. それらの差は正確に 1.0 ではなく、実際、差も正確に保存することはできません。
Double.Equalsの MSDN エントリから:
比較の精度
Equals メソッドは注意して使用する必要があります。これは、2 つの値の精度が異なるため、2 つの明らかに同等の値が等しくない場合があるためです。次の例では、Double 値 .3333 と、1 を 3 で除算して返される Double が等しくないことを報告しています。
...
同等性を比較するのではなく、2 つの値の差の許容範囲を定義することを推奨する手法の 1 つです (値の 0.01% など)。2 つの値の差の絶対値がそのマージン以下である場合、その差は精度の差によるものである可能性が高く、したがって、値が等しい可能性があります。次の例では、この手法を使用して、前のコード例で等しくないことが判明した 2 つの Double 値である .33333 と 1/3 を比較しています。
多くの「等しい」比較を行う必要がある場合は、比較のために .NET 3.5 で小さなヘルパー関数または拡張メソッドを作成することをお勧めします。
public static bool AlmostEquals(this double double1, double double2, double precision)
{
return (Math.Abs(double1 - double2) <= precision);
}
これは次のように使用できます。
double d1 = 1.000001;
double d2 = 0.000001;
bool equals = (d1 - d2).AlmostEquals(1.0, 0.0000001);
この非常によく似た質問を参照してください: C#.NET: Is it safe to check floating point values for equality to 0?
これは、コンピューターが基数 2 で計算を行うため、限られた桁数では多くの 10 進浮動小数点数を正確に表すことができないためです。
浮動小数点数を使用しているためです。
アプリケーションでそのような演算を行う場合は、decimal
型を使用する必要があります
decimal d1 = 1.000001M;
decimal d2 = 0.000001M;
Console.WriteLine((d1 - d2) == 1.0M); // evaluates as true
これは、結果が正確に 1.0 ではなく、1.000000000001 のようなものである可能性があるため、浮動小数点の精度の問題が原因である可能性があります。
これは、浮動小数点型が基数 10 表現ではなく基数 2 を使用して数値を格納するために発生します。これにより、 double は 0.1 のような値を正確に格納できないという結果になります。たとえば、0.1 は単一の値 0.100000001490116119384765625 で表されます。
エラーを取り除くには Decimal を使用する必要があります。
問題は両方で同じであると言われているPythonドキュメントを参照してください。