3

以下 C++ 程序预期输出0.300000000000000040000

cout << setprecision(40) << (0.1 + 0.2) << endl;

但是下面的 C# 代码:

System.Console.WriteLine("{0:F40}", 0.1+0.2);

...意外输出0.3000000000000000000000000000000000000000,而它(预期)评估0.1+0.2 == 0.3False

“4”在哪里,我如何输出它?

4

2 回答 2

6

目前尚不清楚您是否想要4 后跟零,但我有一些代码可以让您打印出 any 的确切十进制值double

所以作为一个测试应用程序:

using System;

class Test
{
    static void Main(string[] args)
    {
        double d1 = 0.1;        
        double d2 = 0.2;
        Console.WriteLine(DoubleConverter.ToExactString(d1 + d2));
        Console.WriteLine(DoubleConverter.ToExactString(0.3));
    }
}

结果:

0.3000000000000000444089209850062616169452667236328125
0.299999999999999988897769753748434595763683319091796875

我怀疑内置的 .NET 格式化程序拒绝给你“4”,理由是那时数字不能被“信任”。它们只是与哪个值恰好最接近您真正目标的值有关的噪音。

从文档中System.Double

默认情况下,Double 值包含 15 位精度的十进制数字,但内部维护最多 17 位数字。

于 2012-10-22T20:03:59.343 回答
1

如果你说你会得到什么

System.Console.WriteLine("{0:R}", 0.1+0.2);

像这样的格式字符串"F40"只会在字符串的末尾添加零。与 just 相比,它不会为您提供额外的精度"G"。另一方面,如果(且仅当)有必要将数字与更接近字符串的数字区分开来,"R"则 , 将显示两个额外的数字(如果两个数字中的最后一个是 ,则显示一个) 。0"G"

另外:为了更好地理解格式字符串在 .NET 中的工作方式,请尝试运行以下代码:

double a = BitConverter.ToDouble(new byte[] { 49, 51, 51, 51, 51, 51, 211, 63, }, 0);
double b = BitConverter.ToDouble(new byte[] { 50, 51, 51, 51, 51, 51, 211, 63, }, 0);
double c = BitConverter.ToDouble(new byte[] { 51, 51, 51, 51, 51, 51, 211, 63, }, 0);
double d = BitConverter.ToDouble(new byte[] { 52, 51, 51, 51, 51, 51, 211, 63, }, 0);
double e = BitConverter.ToDouble(new byte[] { 53, 51, 51, 51, 51, 51, 211, 63, }, 0);

Console.WriteLine("using G:");
Console.WriteLine(a.ToString());
Console.WriteLine(b.ToString());
Console.WriteLine(c.ToString());
Console.WriteLine(d.ToString());
Console.WriteLine(e.ToString());
Console.WriteLine("using F40:");
Console.WriteLine(a.ToString("F40"));
Console.WriteLine(b.ToString("F40"));
Console.WriteLine(c.ToString("F40"));
Console.WriteLine(d.ToString("F40"));
Console.WriteLine(e.ToString("F40"));
Console.WriteLine("using R:");
Console.WriteLine(a.ToString("R"));
Console.WriteLine(b.ToString("R"));
Console.WriteLine(c.ToString("R"));
Console.WriteLine(d.ToString("R"));
Console.WriteLine(e.ToString("R"));

在这里,a, b, c, d, 和e是“邻居”作为System.Doubles 从字节数组中可以明显看出。您应该看到格式字符串仅在,和,"R"的情况下提供额外的数字。对于,不需要额外的数字,但很明显,如果要使用 17 个数字编写,则 17 个数字中的最后两个不会是(另请参阅 Jon Skeet 对 .NET 中内置方法的完整十进制扩展的回答不会轻易给你)。abdecc00

于 2012-10-22T20:53:47.523 回答