1

我遇到了以下算术问题。

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

double d1 = 1.000001;

double d2 = 0.000001;

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

9 回答 9

14

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

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


3)愚蠢的算术

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

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

答:这里的所有值都存储为二进制浮点数。采用虽然1.00001实际上存储在1.00001实际上存储为1.00000099999999322998046695600470493236333362046936/30801,00017333362046956/303033339303936/3099999999981deraiver] hys,而1.000001实际上是1.000001的实际存储为1.00000099999999322998046932999804695633362046956004798936633398049366/3080807366455078 它们之间的差值不完全是 1.0,实际上也不能准确地存储差值。


于 2009-04-06T11:15:39.787 回答
3

从Double.Equals的 MSDN 条目中:

比较精度

应谨慎使用 Equals 方法,因为由于两个值的精度不同,两个明显等效的值可能不相等。下面的示例报告 Double 值 .3333 和通过将 1 除以 3 返回的 Double 不相等。

...

一种推荐的技术不是比较相等性,而是定义两个值之间的可接受差异范围(例如其中一个值的 0.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 equal to 0?

于 2009-04-06T11:19:13.727 回答
2

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

于 2009-04-06T11:15:10.723 回答
2

因为您使用的是浮点数。

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

于 2009-04-06T11:16:42.967 回答
2

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

decimal d1 = 1.000001M;

decimal d2 = 0.000001M;

Console.WriteLine((d1 - d2) == 1.0M); // evaluates as true
于 2009-04-06T11:25:37.907 回答
1

这可能是由于浮点精度问题,因为您的结果可能不完全是 1.0,但可能类似于 1.000000000001

于 2009-04-06T11:15:35.997 回答
1

发生这种情况是因为浮点类型使用以 2 为基数而不是以 10 为基数的表示存储数字。这导致 double 无法准确存储像 0.1 这样的值。例如 0.1 由单个值 0.100000001490116119384765625 表示。

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

于 2009-04-06T11:15:57.070 回答
1

这是由于浮点数在 CPU 中的工作方式,它不是 C# 特定的。有关更多信息,请参阅Wikipedia 条目和此处的论文。

简短的回答是浮点数没有存储为精确的表示,因此使用“==”进行比较不会以您尝试使用它的方式工作。

于 2009-04-06T11:18:15.100 回答
0

看看 python 文档必须说这两个问题是一样的:

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

于 2009-04-06T11:17:02.327 回答