我有一个浮点值: 12345.6489
当我使用以下方式进行格式化:
(12345.6489f).ToString("F1")
然后我得到的结果是:
12345.7
但是这是不正确的,因为它应该是12345.6。
有人明白为什么会发生这种情况吗?另一个提示是,在格式化之前将其转换为double会返回正确的结果,而如果我的浮点值稍小,例如1234.6489,那么我也会得到正确的结果。
我有一个浮点值: 12345.6489
当我使用以下方式进行格式化:
(12345.6489f).ToString("F1")
然后我得到的结果是:
12345.7
但是这是不正确的,因为它应该是12345.6。
有人明白为什么会发生这种情况吗?另一个提示是,在格式化之前将其转换为double会返回正确的结果,而如果我的浮点值稍小,例如1234.6489,那么我也会得到正确的结果。
.ToString("G")
,它将被正确地四舍五入为12345.65
。如果您对四舍五入后的数字进行一位小数的舍入,则会出现问题。当我早些时候调查自己的问题时,我还发现了一些无法解释为两次舍入错误的示例,因此也要检查该线程。
补充:请注意,任何可以由float
(精确)表示的数字也可以(带有许多零位)由double
表示。可以使用以下技巧(该问题也提到了):float x = 12345.6489f;
string trick = ((double)x).ToString("F1");
Double
也不是精确的,会出现类似的怪异情况。它们只是具有不同的精度和范围。 - Jon Skeet[MethodImpl(MethodImplOptions.InternalCall)]
,所以没有 IL。 - David Heffernanfloat
比具有 7 个有效数字的十进制数更精确,但也有一些地方不是这样。在这些地区,由于ToString()
只提供了 7 位小数,因此会得到有趣的结果。例如:在接近 90 亿(9E+09f)时,具有 7 位数字的十进制数的精度为 1000,而float
的精度仅为 1024。因此,例如float x = 9E+09f; Console.WrireLine(x);
将会给出一个惊喜(9000000000 是 512 对 1024 取模)。 - Jeppe Stig Nielsenfloat
是32位IEEE单精度浮点数,最接近12345.6489
的可表示值正好是12345.6484375
。比它大的下一个可表示值正好是12345.6494140625
。因此,有足够的精度来正确获取小数点后一两位数字。对于double
(IEEE 64位),周围的值分别为12345.648899999998320708982646465301513671875
和12345.64890000000013969838619232177734375
。 - Keith Thompson