Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/298.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在.NET中将double转换为字符串不是';t与C+一样精确+;? < > C++程序预期输出 0.30万 cout_C#_Floating Point_Double_Ieee - Fatal编程技术网

C# 在.NET中将double转换为字符串不是';t与C+一样精确+;? < > C++程序预期输出 0.30万 cout

C# 在.NET中将double转换为字符串不是';t与C+一样精确+;? < > C++程序预期输出 0.30万 cout,c#,floating-point,double,ieee,C#,Floating Point,Double,Ieee,不清楚您是否想要精确的4后跟0,但我有一个可以让您打印出任何双精度的精确十进制值 因此,作为一个测试应用程序: using System; class Test { static void Main(string[] args) { double d1 = 0.1; double d2 = 0.2; Console.WriteLine(DoubleConverter.ToExactString(d1 + d2));

不清楚您是否想要精确的4后跟0,但我有一个可以让您打印出任何
双精度
的精确十进制值

因此,作为一个测试应用程序:

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”,理由是在那一点上数字不能被“信任”。它们只是与哪个值恰好与您真正想要的值最接近有关的噪声

从以下文件:

默认情况下,双精度值包含15位小数精度,但内部最多保留17位


如果你说,你会得到什么

System.Console.WriteLine("{0:R}", 0.1+0.2);
类似的
“F40”
只会在字符串末尾添加零。与仅
“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
系统的“邻居”。从字节数组中可以明显看出,双
s。您应该看到,
“R”
格式字符串仅在
a
b
d
e
的情况下提供额外的数字。对于
c
,不需要额外的数字,但很明显如果
c
是17位数字,那么17位数字中的最后两位就不会是
00
(另请参见Jon Skeet的答案,关于.NET中内置的方法无法轻松实现的十进制扩展)。

谢谢。我不希望4后面跟着零,但现在问题是,C++代码中的额外数字在哪里?)而且,如果没有额外的代码,C#无法做到这一点(正如我看到的,还有很多代码)@BorislavStanimirov:不知道C++的哪一面。我不知道是否有更简单的方法来获得C#中的精确值——我很久以前就写过这段代码;我现在有可能改进它。显然这是fpu位精度的问题。您的代码使用IEEE浮点标准的“重新实现”,而{0:R}给出了内部存储的值,该值是可能的最小值,将a==b计算为true。@BorislavStanimirov:是的,R将给出往返格式。虽然内部存储的不是确切的值。@BorislavStanimirov但如果您的目的是查看
0.3
d1+d2
是否相同,从字符串表示法来看,使用
“R”
格式将很有帮助(显示足够多的额外数字以确保答案是“是”还是“否”),而
“F40”
原海报在这方面没有帮助。如果你想要精确的和完整的十进制扩展,它不是内置于.NET中,但是乔恩SkestEp代码的工作很好。你看到的差异是C++编译器增加了0.1 + 0.2,而C编译器优化到0.3(大约)。@ Gabe…这是不可能的。或者更准确地说:就像MS编写一个分数算术引擎,并在编译代码时使用它一样,精确地“优化”这些针对文字和编译时可确定值的操作实例。更准确地说,C#编译器在x86 CPU上运行,因此它以80位扩展精度进行内部计算。这意味着它将常量硬编码为0.29999999999999,而不是0.300000000000000004。这就是我需要的。谢谢