Math.Round(1.225,2) 给出 1.23,它不应该给出 1.22
Math.Round(1.225,2) gives 1.23, shouldn't it give 1.22
AFAIK .NET 的默认回合选项是偶数,所以 Math.Round(1.225,2)
应该给出 1.22 但它给出 1.23.
Math.Round(2.225,2) = 2.22
Math.Round(100.225,2) = 100.22
我试过的所有值都舍入到最接近的偶数,但只有 1.225 和 -1.225 舍入到 1.23 和 -1.23。
主要问题是在float
和double
中,小数位数不是值的一部分,精度不是小数,而是 binary。并且没有有限的二进制数可以准确地表示1.225
。
因此,当您执行 Math.Round(1.225f, 2)
时,您实际上是在执行更类似于 Math.Round(1.22500002f, 2)
的操作 - 不涉及中点舍入。
同样的问题出现在Math.Round(2.225f, 2)
——只是"real"值比2.225f
稍微小,所以结果四舍五入吃下。但是仍然没有涉及中点舍入。
如果需要小数精度,请使用decimal
。 float
和 double
都不是为小数精度设计的 - 它们适用于例如物理计算,但不适用于例如会计。
1.225
不能精确地用浮点数表示,所以你真的在四舍五入 1.225000023841858
。
AFAIK .NET 的默认回合选项是偶数,所以 Math.Round(1.225,2)
应该给出 1.22 但它给出 1.23.
Math.Round(2.225,2) = 2.22
Math.Round(100.225,2) = 100.22
我试过的所有值都舍入到最接近的偶数,但只有 1.225 和 -1.225 舍入到 1.23 和 -1.23。
主要问题是在float
和double
中,小数位数不是值的一部分,精度不是小数,而是 binary。并且没有有限的二进制数可以准确地表示1.225
。
因此,当您执行 Math.Round(1.225f, 2)
时,您实际上是在执行更类似于 Math.Round(1.22500002f, 2)
的操作 - 不涉及中点舍入。
同样的问题出现在Math.Round(2.225f, 2)
——只是"real"值比2.225f
稍微小,所以结果四舍五入吃下。但是仍然没有涉及中点舍入。
如果需要小数精度,请使用decimal
。 float
和 double
都不是为小数精度设计的 - 它们适用于例如物理计算,但不适用于例如会计。
1.225
不能精确地用浮点数表示,所以你真的在四舍五入 1.225000023841858
。