我目前正在阅读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循环时,我可以看到非终止重复的十进制数。你怎么看?我是对还是错?
答案 0 :(得分:12)
double.ToString()使用一般格式,如果未指定精度,则默认为15位小数。所以它确实做了一点舍入,这就是为什么你看到你所看到的。例如,您在问题中指定的0.89999999999999999是小数点后17位。您可以通过sum.ToString("g17")
实际查看整个号码。
您可以在此处找到.net的标准数字格式字符串及其默认精度:http://msdn.microsoft.com/en-us/library/dwhawy9k(VS.80).aspx
答案 1 :(得分:2)
它是ToString的默认行为。如果你在调试器中查看sum,你会得到这个,它会显示没有通过ToString路由的值:
0.0
0.1
0.2
0.30000000000000004
0.4
0.5
0.6
0.7
0.79999999999999993
0.89999999999999991
表明基本行为符合您的预期。
HTH
答案 2 :(得分:2)
简短的回答是:它是浮点数,所以不要指望它是正确的(对于合适的“正确”值)!长期回答者应该了解浮点如何工作以及人们如何使用浮点。 IIRC GNU printf(以及其他我认为的)特殊情况“真的非常接近一个不错的基数10”。