double a = 18.565
return Math.Round(a,2)
..返回18.57 对于其他所有数字,我尝试过银行家的舍入按预期工作,例如Math.Round(2.565,2)返回2.56。
任何线索为什么以及何时发生? 这是错误还是我错过了关于银行家四舍五入的事情?
谢谢..
答案 0 :(得分:16)
马修说,18.565无法准确表达。使用的实际值是18.565000000000001278976924368180334568023681640625(使用DoubleConverter找到),这显然超出了一半。现在我有一种偷偷摸摸的感觉,有时 Math.Round
会考虑一个实际超出中途点的值,但是接近一半可以准确地表示的路点,正好是 at 那一点。但是,我没有看到任何描述应用情况的文档,显然在这种情况下并没有发生。我不想依赖它。
当然,即使是舍入值也不是18.57。它实际上是18.57000000000000028421709430404007434844970703125。
从根本上说,如果您真的非常关心准确表示小数值,那么您应该使用decimal
。这不仅仅是Math.Round
- 它涉及处理浮点值的每个方面。
确实为Math.Round
提供正确的价值,当然:
decimal m = 18.565m;
Console.WriteLine(Math.Round(m, 2)); // Prints 18.56
答案 1 :(得分:5)
18.565无法准确表示为双精度数。因此,二进制表示略高,因此它向上舍入。如果你使用十进制:
decimal a = 18.565m;
return Math.Round(a,2)
它可以准确表示,你不会遇到这个问题。
答案 2 :(得分:1)
我的猜测是FP表示意味着它实际上不是尾随5; FP的危险!
但这很好,但是:
decimal a = 18.565M; // <===== decimal
var s = Math.Round(a, 2);
答案 3 :(得分:0)
Double是浮点值,所以如果你把它写成18.565,它实际上在内存中就像是18.565000000000000000000000000000000000001,因此它超过了中点。