c#中的打印增量为0.1

时间:2009-05-19 19:17:22

标签: c# floating-point

我目前正在阅读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循环时,我可以看到非终止重复的十进制数。你怎么看?我是对还是错?

3 个答案:

答案 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”。