双打格式化输出在C# [英] Formatting doubles for output in C#

查看:148
本文介绍了双打格式化输出在C#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

运行到相关的快速实验是在.NET破碎双倍增?和阅读一对夫妇在C#字符串格式化的文章,我觉得这:

Running a quick experiment related to Is double Multiplication Broken in .NET? and reading a couple of articles on C# string formatting, I thought that this:

{
    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 $ C $的c:

Would be the C# equivalent of this C code:

{
    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#产生输出:

However the C# produces the output:

6.9
  6.90000000000000000000
+ 0.00000000000000088818
= 6.90000000000000000000

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

6.900000                          
  6.89999999999999946709          
+ 0.00000000000000088818          
= 6.90000000000000035527

这是怎么回事?

(Microsoft .NET Framework版本3.51 SP1 / Visual Studio的C#2008前preSS版)

( Microsoft .NET Framework Version 3.51 SP1 / Visual Studio C# 2008 Express Edition )


我在数值计算和经验的背景下实现区间算术 - 在各种平台上 - 估计由于precision在复杂的数字系统的极限误差的技术。为了获得赏金,不要试图对存储precision解释 - 在这种情况下,它是一个64位的双之一ULP的差异。

I have a background in numerical computing and experience implementing interval arithmetic - a technique for estimating errors due to the limits of precision in complicated numerical systems - on various platforms. To get the bounty, don't try and explain about the storage precision - in this case it's a difference of one ULP of a 64 bit double.

要获得赏金,我想知道如何(或者是否)的.Net可以格式化一倍,所要求的precision在C code作为可见。

To get the bounty, I want to know how (or whether) .Net can format a double to the requested precision as visible in the C code.

推荐答案

的问题是,.NET总会一轮之前双击 15显著十进制数字的 的应用您的格式,不管你的格式,不管是二进制数的精确十进制值要求的precision的。

The problem is that .NET will always round a double to 15 significant decimal digits before applying your formatting, regardless of the precision requested by your format and regardless of the exact decimal value of the binary number.

我猜想,在Visual Studio调试器直接访问内部的二进制数自己的格式/显示子程序,所以你的C#code之间的差异,你的C code和调试器。

I'd guess that the Visual Studio debugger has its own format/display routines that directly access the internal binary number, hence the discrepancies between your C# code, your C code and the debugger.

有什么内置的,将允许您访问的双击,或使你格式化双<确切的十进制值/ code>来小数的具体数量,但你可以通过拾取除了内部的二进制数,并重建它作为一个字符串重新十进制值presentation自己做。

There's nothing built-in that will allow you to access the exact decimal value of a double, or to enable you to format a double to a specific number of decimal places, but you could do this yourself by picking apart the internal binary number and rebuilding it as a string representation of the decimal value.

另外,你可以使用乔恩斯基特的 DoubleConverter (从他的二进制浮点和.NET文章)挂钩。这有它返回一个的精确十进制值 ToExactString 方法双。你可以很容易地修改这个以使输出的舍入到一个特定的precision。

Alternatively, you could use Jon Skeet's DoubleConverter class (linked to from his "Binary floating point and .NET" article). This has a ToExactString method which returns the exact decimal value of a double. You could easily modify this to enable rounding of the output to a specific precision.

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

这篇关于双打格式化输出在C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆