.Net中Math.Round与四舍五入
1> 有不少人误将Math.Round函数当作四舍五入函数在处理, 结果往往不正确, 实际上Math.Round采用的是国际通行
的是 Banker 舍入法.
Banker's rounding(银行家舍入)算法,即四舍六入五取偶。事实上这也是 IEEE 规定的舍入标准。因此所有
符合 IEEE 标准的语言都应该是采用这一算法的. 这个算法可以概括为:“四舍六入五考虑,五后非零就进一,
五后皆零看奇偶,五前为偶应舍 去,五前为奇要进一。”
请看下面的例子:
Math.Round(3.44, 1); //Returns 3.4. 四舍
Math.Round(3.451, 1); //Returns 3.5 五后非零就进一
Math.Round(3.45, 1); //Returns 3.4. 五后皆零看奇偶, 五前为偶应舍 去
Math.Round(3.75, 1); //Returns 3.8 五后皆零看奇偶,五前为奇要进一
Math.Round(3.46, 1); //Returns 3.5. 六入
如果要实现我们传统的四舍五入的功能,一种比较简单,投机的方法就是在数的后面加上0.0000000001,很小的一
个数.因为"五后非零就进一", 所以可以保证5一定进一.
注:
2>.net实现四舍五入法
如果问C#程序员,四舍五入方法是怎么写的。很多人上来就会轻而易举的写上一个Math.Round()方法。但却不
知,其中可悲的奥妙之处!
试写出下列计算结果:
Math.Round(0.5)
Math.Round(1.5)
肯定有一部分人会写,计算结果为1和2。
那就大错特错了!事实证明,这两个表达式的结果分别为0和2!这就是很多程序的BUG所在。
细心的程序员们可以看一下MSDN中对Math.Round(Decimal)方法的描述,其中对于返回值的描述如下:
返回值
类型:System.Decimal
最接近参数 d 的整数。如果 d 的小数部分正好处于两个整数中间,其中一个整数为偶数,另一个整数为奇数,
则返回偶数。
这就已经充分解释了,为什么上面的两个表达式的返回值分别为0和2。也证明了简单的Math.Round
(Decimal)方法无法实现四舍五入的功能!
3>.net真正实现四舍五入是利用Math.Round()重载方法
.NET中的Math.Round(),还提供另外一些重载方法,其中一个是Math.Round(Decimal, MidpointRounding)方法
,通过这个方法,可以实现对十进制小数的四舍五入。方法如下:
Math.Round(Decimal, MidpointRounding.AwayFromZero)
e.g:
2.3
1>返回整数
则: Math.Round( 0, MidpointRounding.AwayFromZero )
1>返回小数点后含1位
则: Math.Round( 1, MidpointRounding.AwayFromZero )
即Decimal表明返回小数点后几位。
大功告成!让我们的程序告别BUG!