有没有办法精确地格式化C#double?

有没有办法精确地格式化C#double?,c#,floating-point,floating-point-precision,C#,Floating Point,Floating Point Precision,有没有一种方法可以得到一个字符串,该字符串显示一个双精度的精确值,所有小数点都需要以10为基数来表示其精确值 例如(via),当您键入 double d = 0.3; d的实际值正好是 0.299999999999999988897769753748434595763683319091796875 每一个二进制浮点值(忽略无穷大和NaN)都将解析为一个终止的十进制值。因此,如果输出中有足够的精度数字(在本例中为55位),则始终可以取double中的任何值,并以十进制显示其精确值。当需要解释浮

有没有一种方法可以得到一个字符串,该字符串显示一个
双精度的精确值,所有小数点都需要以10为基数来表示其精确值

例如(via),当您键入

double d = 0.3;
d
的实际值正好是

0.299999999999999988897769753748434595763683319091796875
每一个二进制浮点值(忽略无穷大和NaN)都将解析为一个终止的十进制值。因此,如果输出中有足够的精度数字(在本例中为55位),则始终可以取
double
中的任何值,并以十进制显示其精确值。当需要解释浮点运算的奇怪之处时,能够向人们展示精确的值将非常有用。但是有没有办法在C#中做到这一点呢

我已经尝试了所有的方法,无论是否指定了精度,都没有给出确切的值。一些亮点:

  • d.ToString(“n55”)
    输出
    0.3
    后接54个零——它按照通常的方式“四舍五入到您可能想要看到的内容”,然后在末尾加上更多的零。如果我使用
    0.00000…
  • d.ToString(“r”)
    为您提供了一个足够精确的值,如果您对其进行解析,您将获得与开始时相同的位模式,但在本例中,它只输出
    0.3
    。(如果我处理的是计算结果,而不是常数,这将更有用。)
  • d.ToString(“e55”)
    输出
    2.999999999999999000000000000000000000000000000000000000000000E-001
    ——一些精度,但不是我想要的全部精度

是否有一些我遗漏的格式字符串,或其他库函数,或NuGet package或其他库,能够将
double
转换为具有完全精度的字符串?

我相信您可以根据您希望通过显示器实现的目标来实现这一点:

考虑这一点:

Double myDouble = 10/3;

myDouble.ToString("G17");
您的输出将是:

3.3333333333333335
请参阅此链接了解原因:

默认情况下,返回值仅包含15位精度,但内部最多保留17位精度。如果此实例的值大于15位,则ToString将返回正数infinitySymbol或负数infinitySymbol,而不是预期的数字。如果需要更高的精度,请使用“G17”格式规范指定格式,该格式规范始终返回17位精度,或使用“R”格式规范,如果数字可以用该精度表示,则返回15位;如果数字只能用最大精度表示,则返回17位

您还可以执行以下操作:

myDouble.ToString("n16");
这将丢弃第16和第17个噪波数字,并返回以下内容:

3.3333333333333300
如果要将实际变量值显示为数字,可能需要使用“G17”。如果您试图以高精度显示计算中使用的数值,则需要使用“n16”。

如果您希望抑制尾随零,并避免使用科学符号,则可以尝试使用#占位符。虽然对于非常小的数字,您将需要很多,例如:

Console.WriteLine(double.Epsilon.ToString("0.########....###"));

这不是OP想要的,一开始我也有同样的想法,我做了一个类似于你答案的评论,但后来删除了。你可以使用John Skeet的Double Converter类:看到这个答案:我必须问的问题是:你需要这个做什么?如果你解释一下你想要它做什么,也许我们可以给你一个更好的方法来获取它。超过第16个有效位的数据需要准确地表示双精度的二进制值。该二进制值遵循某种语言和IEEE浮点标准规则的组合。看到这些数字对于理解浮点行为和舍入非常重要。在Java中,我会转换成BigDecimal,它的默认toString产生它的精确值。在.NET中,没有办法以本机方式实现这一点,你必须像Jon Skeet的库那样,从BitConverter中获取位,然后手工解析出double。这是一个没有意义的数字字符串,任何人都不想看到。使用BitConverter.DoubleToInt64Bits().ToString()可以得到一个短得多的格式。如果不起作用,.NET framework会在应用格式化程序之前进行预循环。