题
double a = 18.565
return Math.Round(a,2)
..返回18.57。
对于其他每一个数字,我尝试的银行家的舍入都按预期工作,例如Math.Round(2.565,2)返回2.56。
有任何线索为什么以及何时发生?这是错误还是我错过了银行家的四舍五入?
谢谢..
解决方案
正如马修说的那样,无法准确代表18.565。使用的实际值是18.565000000000000012789769243681818034568023681640625(发现使用使用 DoubleConverter),显然超出了一半。现在我有一种偷偷摸摸的感觉 有时 Math.Round
将考虑一个值 实际上 超出了半程点,但与准确表示的相同,与确切所能准确表示的一半 在 这一点。但是,我还没有看到任何描述所应用情况的文档,在这种情况下显然没有发生。我不想依靠它。
当然,即使是圆形值也不是18.57。实际上是18.570000000000000284217094304040074344444970703125。
从根本上说,如果您真的非常关心准确表示十进制值,则应该使用 decimal
. 。这不仅是 Math.Round
- 它进入处理浮点值的各个方面。
那 做 给出正确的价值 Math.Round
, , 当然:
decimal m = 18.565m;
Console.WriteLine(Math.Round(m, 2)); // Prints 18.56
其他提示
18.565不能完全表示为双重。因此,二进制表示略高,因此圆形。如果您使用小数:
decimal a = 18.565m;
return Math.Round(a,2)
它可以完全代表,您将不会遇到这个问题。
我的猜测是FP表示意味着它实际上并不是一个落后的5; FP的危险!
但是,这很好:
decimal a = 18.565M; // <===== decimal
var s = Math.Round(a, 2);
double是一个浮点值,因此,如果您将其写入18.565,它实际上在内存中,类似于18.5650000000000000000000000000000000001,因此它不仅仅是中点。
不隶属于 StackOverflow