我有一个浮动值:12345.6489
当我使用以下格式进行格式化时:
(12345.6489f)的ToString( “F1”)
然后我得到
的结果12345.7
但这是不正确的,因为它应该是12345.6。
有谁理解为什么会这样?另一个提示是在格式化之前转换为double会返回正确的结果,如果我的浮点值稍微小一些,例如1234.6489,那么我也得到正确的结果。
答案 0 :(得分:3)
这似乎与我前一段时间提出的问题有关:Round-twice error in .NET's Double.ToString method
请注意,如果您拨打号码.ToString("G")
,则会将其正确舍入为12345.65
。如果将四舍五入的数字四舍五入到一位小数,则会出现问题。
当我早些时候调查我自己的问题时,我也发现了一些无法解释为二次错误的例子,所以也检查一下这个帖子。
添加:请注意,float
可以(确切地)表示的任何数字也可以double
表示(有很多零位) 。可以使用以下技巧(问题也提到):
float x = 12345.6489f;
string trick = ((double)x).ToString("F1");
答案 1 :(得分:1)
感谢您提出这个问题!从事调查非常有趣。但是我想提一下奖牌的其他一方。你问了以下问题:
(12345.6489f)的ToString( “F1”)
然后我得到
的结果12345.7
但这是不正确的,因为它应该是12345.6。
好吧,我想知道你是如何弄清楚什么是 正确 以及什么是 错误 输出这个字符串格式化例程?那些格式化字符串不应该用于舍入目的。并且文档清楚地says关于它:
老实说,当我第一次看到你的问题中的数字时 - 第一个想法是围绕Hans Passant在他的回答中提到的舍入算法。所以,我对选择这样的算法并不感到惊讶,它实际上非常直观:)我甚至不会感到惊讶他们会将普通截断视为浮点数格式化的算法。它仍然非常准确和有效。
所以,尽管事实如此 这是非常有趣的,看起来像一个bug /悖论/奇迹,这实际上只是我们错误的期望来自功能设计(并且实际上做得很好)的另一件事。