为什么C#以这种方式舍入?

时间:2014-01-30 03:42:45

标签: c# floating-point rounding

所以,我有这个浮点数:

(float)-123456.668915

这是一个随机选择的数字,因为我正在为我写的一大块BCD代码做一些单元测试。每当我将上面的数字与一个字符串("-123456.668915"比较清楚)进行比较时,我就会遇到C#如何舍入数字的问题。它将其舍入为-123456.7。已在NUnit中检查并使用直接控制台输出。

为什么这样四舍五入?根据MSDN,浮点范围约为-3.4 * 10 ^ 38到+3.4 * 10 ^ 38,精度为7位。除非我完全遗漏了某些内容,否则上述数字在该范围内 ,并且在小数点后仅有6位数。

感谢您的帮助!

2 个答案:

答案 0 :(得分:14)

  

根据MSDN,浮点范围约为-3.4 * 10 ^ 38到+3.4 * 10 ^ 38,精度为7位。除非我完全遗漏了某些内容,否则以上数字在该范围内,并且在小数点后只有6位数。

“小数点后6位”与“6位精度”不同。精度的位数是可以可靠保持的有效位数。您的号码有 12 有效数字,因此float无法完全表示它是完全没有意义的。

请注意,它(应该)舍入到的数字,-123456.7, 有7位有效数字。事实上,这也不是你float的价值。我强烈怀疑完全值是-123456.671875,因为它是最接近float到-123456.668915。但是,当您将精确值转换为字符串表示时,结果只有7位数,部分原因是除此之外,数字无论如何都不是真正有意义。

您应该阅读my article about binary floating point in .NET了解更多详情。

答案 1 :(得分:0)

浮点类型具有24个有效位的精度(非正规除外),相当于24 log 10 2≈7.225有效十进制数字。数字-123456.668915有12位有效数字,因此无法准确显示。

舍入为24位有效位的实际二进制值为-11110001001000000.1010110。这相当于分数-7901227/64 = -123456.671875。舍入到7位有效数字会给出您看到的-123456.7