C#中的”四舍五入”--银行家算法,即:四舍六入五取偶

28 篇文章 1 订阅

很多人都知道Math.Round()是C#中用来做四舍五入,保留指定小数位的。但实际上它并不是真正的四舍五入,而是银行家算法的“四舍六入五取偶”,事实上这也是IEEE的规范,因此所有符合IEEE标准的语言都应该采用这样的算法。其规则如下:

  • 1、当舍去位的数值小于5时:直接舍去
  • 2、当舍去位的数值大于6时:进位加1
  • 3、当舍去位的数值等于5时,分两种情况:

(1)若5后面有其他非0数字(即5不是最后一位)时,进位加1。

 (2)若5后面只有0(即5是最后一位)时,则根据5的前一位的奇偶来判断,前一位为奇数则进位加1,为偶数则舍去。

遇到5需要舍去的情况只有一种,即5是最后一位有效数且前一位数是偶数。数字的精度越大,则这个算法就越像真正的四舍五入。

我们使用这个函数时,用来处理的数字通常是那些有n位小数的数字,而我们用于显示的通常也就只有2-4位,所以这也就不容易发现这个问题。

可能纯文字描述不太好理解,举几个例子:

  Math.Round(1.14, 1); //结果:1.1
  Math.Round(1.25, 1); //结果:1.2 五是最后一位且前一位为偶数,也舍去
  Math.Round(1.15, 1); //结果:1.2 五是最后一位但前一位为奇数,进位加一
  Math.Round(1.16, 1); //结果:1.2

如果希望实现中国式的标准的“四舍五入”法,应该怎么办呢?

从.NET 2.0 开始,Math.Round 方法提供了一个枚举选项--MidpointRounding.AwayFromZero,可以用来实现传统意义上的"四舍五入"。

即: 

Math.Round(4.5); //结果为 4
Math.Round(4.5, MidpointRounding.AwayFromZero); //结果为 5

结果为 5。

MSDN文档中这个MidpointRounding.AwayFromZero的描述是“当一个数字是其他两个数字的中间值时,会将其舍入为两个值中绝对值较小的值。”

实际上从 .NET 2.0 发布以来,网上已经有很多人都指出了这个翻译错误(原文实际是 When a number is halfway between two others, it is rounded toward the nearest number that is away from zero.),实际上应该是取绝对值较大的值。可是很遗憾,.NET 3.0, .NET 3.5 的文档中,这个翻译错误依然没有改正过来。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值