9
double a = 18.565
return Math.Round(a,2)

..返回 18.57。
对于我尝试过的所有其他数字,银行家的四舍五入按预期工作,例如 Math.Round(2.565,2) 返回 2.56。

任何线索为什么以及何时发生?是错误还是我错过了有关银行家四舍五入的内容?

谢谢..

4

4 回答 4

17

正如 Matthew 所说,18.565 无法准确表示。使用的实际值为 18.565000000000001278976924368180334568023681640625 (使用DoubleConverter找到),这显然超出了一半。现在我有一种偷偷摸摸的感觉,有时 Math.Round会考虑一个实际上超出中点的值,但它与可以准确表示的中点一样接近,就像恰好那个点一样。但是,我还没有看到任何描述应用情况的文档,显然在这种情况下不会发生这种情况。我不想依赖它。

当然,即使四舍五入的值也不完全是 18.57。它实际上是 18.57000000000000028421709430404007434844970703125。

从根本上说,如果您真的非常关心准确地表示十进制值,那么您应该使用decimal. 这不仅仅是在Math.Round- 它涉及处理浮点值的各个方面。

当然,这确实给出了正确的值Math.Round

decimal m = 18.565m;
Console.WriteLine(Math.Round(m, 2)); // Prints 18.56
于 2010-09-23T06:13:32.267 回答
5

18.565 不能精确地表示为双精度数。因此,二进制表示略高,因此向上取整。如果使用十进制:

decimal a = 18.565m;
return Math.Round(a,2)

它可以准确地表示,你不会有这个问题。

于 2010-09-23T06:11:23.470 回答
1

我的猜测是 FP 表示意味着它实际上不是尾随 5。FP的危险!

不过,这很好用:

        decimal a = 18.565M; // <===== decimal
        var s = Math.Round(a, 2);
于 2010-09-23T06:13:39.847 回答
0

Double 是一个浮点值,所以如果你把它写成 18.565,它实际上在内存中是 18.565000000000000000000000000000000001,因此它超过了中点。

于 2010-09-23T06:14:02.327 回答