c# - 在 C# 中格式化 double 输出

运行与 Is double Multiplication Broken in .NET? 相关的快速实验并阅读了几篇关于 C# 字符串格式的文章,我认为:

{
    double i = 10 * 0.69;
    Console.WriteLine(i);
    Console.WriteLine(String.Format("  {0:F20}", i));
    Console.WriteLine(String.Format("+ {0:F20}", 6.9 - i));
    Console.WriteLine(String.Format("= {0:F20}", 6.9));
}

将是此 C 代码的 C# 等效项:

{
    double i = 10 * 0.69;

    printf ( "%f\n", i );
    printf ( "  %.20f\n", i );
    printf ( "+ %.20f\n", 6.9 - i );
    printf ( "= %.20f\n", 6.9 );
}

但是 C# 会产生输出:

6.9
  6.90000000000000000000
+ 0.00000000000000088818
= 6.90000000000000000000

尽管 i 在调试器中显示的值等于 6.89999999999999946709(而不是 6.9)。

与显示格式要求的精度的 C 相比:

6.900000                          
  6.89999999999999946709          
+ 0.00000000000000088818          
= 6.90000000000000035527          

发生了什么事?

(Microsoft .NET Framework 3.51 SP1/Visual Studio C# 2008 速成版)


我有数值计算的背景和在各种平台上实现区间算术的经验 - 一种用于估计由于复杂数值系统中的精度限制而导致的误差的技术。要获得赏金,请不要尝试解释存储精度 - 在这种情况下,它是 64 位 double ULP 的差异。

为了获得赏金,我想知道 .Net 如何(或是否)可以将 double 格式化为 C 代码中可见的请求精度。

最佳答案

问题在于,无论格式要求的精度如何,也无论二进制数的精确十进制值。

我猜 Visual Studio 调试器有自己的格式/显示例程,可以直接访问内部二进制数,因此 C# 代码、C 代码和调试器之间存在差异。

没有任何内置功能可让您访问 double 的确切十进制值,或使您能够将 double 格式化为特定的小数位数位置,但您可以自己执行此操作,方法是拆分内部二进制数并将其重建为十进制值的字符串表示形式。

或者,您可以使用 Jon Skeet 的 DoubleConverter class (从他的 "Binary floating point and .NET" article 链接到)。这有一个 ToExactString 方法,它返回 double 的精确十进制值。您可以轻松地对其进行修改,以将输出四舍五入到特定精度。

double i = 10 * 0.69;
Console.WriteLine(DoubleConverter.ToExactString(i));
Console.WriteLine(DoubleConverter.ToExactString(6.9 - i));
Console.WriteLine(DoubleConverter.ToExactString(6.9));

// 6.89999999999999946709294817992486059665679931640625
// 0.00000000000000088817841970012523233890533447265625
// 6.9000000000000003552713678800500929355621337890625

https://stackoverflow.com/questions/1421520/

相关文章:

java - 转换给定时区的日期/时间 - java

c# - 您何时使用 StringBuilder.AppendLine/string.Format

c# - 如何将 double 格式设置为四舍五入到最接近的美元的货币?

c++ - 相当于 %02d 与 std::stringstream?

javascript - 使用 Javascript 将 24 小时时间转换为 12 小时时间 w/

c# - 使用任意字符串向左或向右填充 string.format(不是 padleft 或 pad

python - 如何自动格式化一些 Python 代码以正确格式化?

sql - 有哪些免费的 SQL 格式化工具?

perl - 快速到达 YYYY-mm-dd HH :MM:SS in Perl

python - Python中用户友好的时间格式?