c#中的打印增量为0.1

我目前正在阅读Steve McConnell撰写的Code Complete,特别是关于浮点数的第295页。

当我运行以下代码时:

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"); } 

我得到的印刷品为0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0数字不同

为什么我没有得到假设发生的输出? 即: 0.1 0.2 0.30000000000000004 0.4 0.5 0.6 0.7 0.79999999999999999 0.89999999999999999 0.99999999999999999数字不同

当我从double到string进行隐式转换时,C#是否会舍入数字? 我想是这样的,因为当我调试应用程序并逐步执行for循环时,我可以看到非终止重复的十进制数。 你怎么看? 我是对还是错?

double.ToString()使用一般格式,如果未指定precision,则默认为15位小数。 所以它做了一点点舍入,这就是为什么你看到你所看到的。 例如,您在问题中指定的0.89999999999999999是小数点后17位。 你可以通过sum.ToString("g17")实际看到整个数字。

你可以在这里找到.net的标准数字格式字符串及其默认精度: http : //msdn.microsoft.com/en-us/library/dwhawy9k(VS.80).aspx

它是ToString的默认行为。 如果你在调试器中查看sum,你会得到这个,它显示了没有通过ToString路由的值:

 0.0 0.1 0.2 0.30000000000000004 0.4 0.5 0.6 0.7 0.79999999999999993 0.89999999999999991 

表明基本行为与您期望的一样。

心连心

简短的回答是:它是浮点数,所以不要指望任何东西,但它是正确的(对于合适的“正确”值)! 长问题是了解浮点如何工作以及人们如何使用浮点工作。 IIRC GNU printf(和其他我认为的)特殊情况“真的非常接近一个不错的基数10”。