为什么这个问题的结果不同?

时间:2009-04-06 11:11:45

标签: c# floating-point floating-accuracy

我遇到了以下算术问题。

但结果与正常的数学运算不同,为什么会这样呢?

double d1 = 1.000001;

double d2 = 0.000001;

Console.WriteLine((d1-d2)==1.0);

9 个答案:

答案 0 :(得分:14)

我认为你在Jon Skeet的Brainteasers页面上找到了这个问题?答案在同一网站上列出并解释here

作为参考,这是从该页面复制的答案。


3)愚蠢算术

计算机应该擅长算术,不是吗?为什么打印“假”?

double d1 = 1.000001; double d2 =
0.000001; Console.WriteLine((d1-d2)==1.0);

答案:此处的所有值都存储为二进制浮点数。虽然1.0可以准确存储,但实际存储的是1.000001 1.0000009999999999177333620536956004798412322998046875,并且0.000001实际存储为 0.000000999999999999999954748111825886258685613938723690807819366455078125。它们之间的差异并不完全是1.0,实际上差异也不能完全存储。


答案 1 :(得分:3)

来自Double.Equals的MSDN条目:

  

比较精确度

     

Equals方法应该与。一起使用   谨慎,因为两个显然   等值可能是不等的   两者的精度不同   值。以下示例报告   那个Double值.3333和   通过除以1而得到的双是   不相等的。

     

...

     

而不是比较平等,   一种推荐的技术涉及   定义可接受的边际   两个值之间的差异(例如   其中一个值的.01%)。如果   差异的绝对值   两个值之间小于或   等于那个边际,差异   可能是由于差异造成的   精度,因此,价值   可能是平等的。下列   示例使用此技术进行比较   .33333和1/3,两个Double值   上一个代码示例找到了   不平等。

如果你需要进行大量的“相等”比较,那么在.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 :(得分:2)

这是因为计算机在基数2中进行数学运算,因此许多十进制浮点数不能用有限的位数精确表示。

答案 3 :(得分:2)

因为您使用的是浮点数。

http://docs.sun.com/source/806-3568/ncg_goldberg.html

答案 4 :(得分:2)

如果您在应用程序中进行此类算术运算,则应使用decimal类型

decimal d1 = 1.000001M;

decimal d2 = 0.000001M;

Console.WriteLine((d1 - d2) == 1.0M); // evaluates as true

答案 5 :(得分:1)

这可能是由于浮点精度问题,因为可能你的结果不是1.0,但可能是1.000000000001

答案 6 :(得分:1)

这是因为浮点类型使用基数2而不是基数十表示来存储数字。这导致double无法精确存储0.1之类的值。例如,0.1由单个值0.100000001490116119384765625表示。

你必须使用Decimal来消除错误。

答案 7 :(得分:1)

这是由于浮点数在CPU中的工作方式,而不是C#特定的。有关详细信息,请参阅this维基百科条目和论文here

简短的回答是浮点数不会存储为精确表示,因此使用“==”进行比较不会像您尝试使用它一样。

答案 8 :(得分:0)

看看python docs有什么说法,两个问题都是一样的:

http://docs.python.org/tutorial/floatingpoint.html