使用ToString(“F1”)时浮点的舍入不正确

我有一个浮动值:12345.6489

我使用时格式化:

(12345.6489f)的ToString( “F1”)

然后我得到了结果

12345.7

但这是不正确的,因为它应该是12345.6。

有谁知道为什么会这样? 另一个提示是在格式化之前转换为double会返回正确的结果,如果我的浮点值稍微小一些,例如1234.6489,那么我也得到正确的结果。

这似乎与我前一段时间提出的一个问题有关: 在.NET的Double.ToString方法中出现二次错误

请注意,如果您在号码上调用.ToString("G") ,则会将其正确舍入为12345.65 。 如果将舍入的数字四舍五入到一个小数,则会出现问题。

当我之前调查我自己的问题时,我也发现了一些无法解释为二次错误的例子,所以也检查一下这个线程。

另外:请注意,任何可以由float表示(确切)的数字也可以用float表示(有很多零位)。 可以使用以下技巧(问题也提到):

 float x = 12345.6489f; string trick = ((double)x).ToString("F1"); 

谢谢你的回答! 从事调查非常有趣。 但是我想提一下奖章的其他一方。 你问了以下问题:

(12345.6489f)的ToString( “F1”)

然后我得到了结果

12345.7

但这是不正确的,因为它应该是12345.6。

好吧,我想知道你是如何弄清楚什么是正确的以及这个字符串格式化例程的错误输出是什么? 那些格式化字符串不应该用于舍入目的。 文档清楚地说明了这一点:

http://msdn.microsoft.com/en-us/library/dwhawy9k.aspx#FFormatString


老实说,当我第一次看到你的问题中的数字时 – 第一个想法是围绕汉斯帕斯特在他的答案中提到的舍入算法。 所以,我对选择这样的算法并不感到惊讶,它实际上非常直观:)我甚至不会感到惊讶他们会将普通截断视为浮点数格式化的算法。 它仍然非常准确和有效。

所以,尽管事实上所有这些都非常有趣并且看起来像一个bug /悖论/奇迹,但实际上这只是我们错误的期望来自function设计(并且实际上做得很好)的另一件事。