我一直在与来自SQL (38,30)的C#中的十进制精度作斗争,我终于把它变成了一个四舍五入的怪诞。我知道我可能忽略了显而易见的事情,但我需要一点洞察力。
我遇到的问题是,C#没有产生我认为是一致的输出。
decimal a = 0.387518769125m;
decimal b = 0.3875187691250002636113061835m;
Console.WriteLine(Math.Round(a, 11));
Console.WriteLine(Math.Round(b, 11));
Console.WriteLine(Math.Round(a, 11) == Math.Round(b, 11));产量
0.38751876912
0.38751876913
False呃,0.38751876913?真的?我在这里错过了什么?
来自MSDN
如果小数位中的数字为奇数,则将其更改为偶数。否则,它将保持不变。
为什么我看到不一致的结果?额外的精度不会改变“小数位”的位置.
发布于 2012-04-12 16:13:23
来自MSDN:
如果在
d中有一个非零的数字在decimals十进制位置的右,并且它的值是,则小数位中的数字如果是奇数就会舍入,如果是偶数,则保持不变。如果d的小数位数比decimals少,则d的返回将保持不变。
在你的第一个案例中
decimal a = 0.387518769125m;
Console.WriteLine(Math.Round(a, 11));在第11位的右边,是一个单数,,这个数字是。因此,由于位置11是偶数,所以保持不变的。因此,你会得到
0.38751876912在你的第二个案例中
decimal b = 0.3875187691250002636113061835m;
Console.WriteLine(Math.Round(b, 11));在第11位中,并不是右的一个数字。因此,这是直接向上的小学四舍五入;如果下一个数字大于4,则可以进行舍入。因为第11位右边的数字超过了4(这是5),所以你看
0.38751876913为什么我看到不一致的结果?
你不是。结果与文档完全一致。
发布于 2012-04-12 16:10:34
来自MSDN - Math.Round方法(十进制,Int32)
如果小数小数位置右侧有一个非零数字,其值为5,则小数位置中的数字如果是奇数,则舍入,如果是偶数,则保持不变。如果d的小数比小数少,则返回d不变。 这种方法的行为遵循IEEE标准754,第4节。这种四舍五入有时被称为四舍五入到最近,或银行家的四舍五入。它最大限度地减少了由在单个方向上一致舍入中点值而产生的舍入误差。
注意使用单数非零位数.这与您的第一个示例相对应,但不是第二个示例。
和:
若要控制圆(Decimal,Int32)方法使用的舍入类型,请调用Decimal.Round(Decimal,Int32,MidpointRounding)重载。
发布于 2012-04-12 16:12:23
小数位右边的单数非零位数,其数值为5的部分解释了结果。只有当部分到圆正好为0,5时,舍入规则才起作用。
https://stackoverflow.com/questions/10127427
复制相似问题