打印双精度浮点数

6

在我的系统上,以下代码会打印出 '3.6':

double a = 1.2;
int b = 3;

double c = a * b;

Console.WriteLine(c);

但在调试器中,我可以看到c的值超过了2位数:

enter image description here

我知道可以使用Console.WriteLine("{0:R}", c)来显示完整的表示。这是显示double实际值的唯一和推荐方式吗?


更新

以上面的例子为例,我想打印c,以使如果用户将打印的值插入到带有==的测试代码中,则比较将返回true。 在这种情况下,c == 3.5999999999999996返回true。


你如何展示取决于你想用它做什么。 - usr
2
你想显示几位小数? - MethodMan
其他回答者请注意:真正的问题是关于比较双精度浮点数,而不是格式化输出。我建议@dharmatech更新他们的问题。 - siride
4个回答

8

嗨,Tim。我想显示在调试器中出现的值。使用“N8”甚至“N20”都无法显示该值。 - dharmatech
@dharmatech: 修改了我的答案。为什么你想把它显示得和调试器一样? - Tim Schmelter
我想要显示这个值,以便如果该值被用于 == 进行比较时,测试将返回 true。例如,在这种情况下,c == 3.5999999999999996 确实返回 true。 - dharmatech
@dharmatech:你正在进入危险的领域。阅读此文:http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm - siride

8

3.999999999999996并不是double的实际值,这只是舍入到十五位或其他位数的值。没有内置的方法来显示double所表示的确切值。这真的很糟糕,因为每个正常的double都可以准确地表示为十进制字符串,能够看到这一点会很好。

作为公共服务,我在我的博客上放了一个可以做到这一点的设备的源代码:

http://ericlippert.com/2011/02/17/looking-inside-a-double/

请注意,它使用了Microsoft Solver Foundation的Rational类。如果你没有它,那么你可以免费下载它,或者编写自己的Rational类;这将有助于你的性格塑造。

如果你对double如何在内部工作的主题感兴趣,考虑查看我解释所有这些内容的便利文章的存档。它位于:

http://blogs.msdn.com/b/ericlippert/archive/tags/floating+point+arithmetic/

从底部开始;这些是按时间顺序倒序排列的。


有趣的是您提到自己编写“Rational”类。我所做的项目也有自己的有理数。最终,拥有C#版本的CLN将是很棒的。未来如果主流语言都配备了这样一个完整的数字库,那将会很好。 - dharmatech
我更新了问题并附上了我的实际目标,因为有人提出了疑问。 - dharmatech

4

如果你想返回两位小数,也可以使用不同的方法,比如这样:

double a = 1.2;
int b = 3;
double c = a * b;
var s = string.Format("{0:0.00}", c);
Console.WriteLine(s);

输出 = 3.60

如果您想去掉输出为3.6的最后一个0,可以这样做

var s = string.Format("{0:0.##}", c);

输出结果为 3.6,可以随意尝试调整


不会抑制两个零吗? 应该是: 'var s = string.Format("{0:0.0#}", c);' - Atif Qadri

1
double a = 1.2;
int b = 3;

double c = a * b;
string formatted = c.ToString("N5");
Console.WriteLine(formatted);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接