Round() 四舍五入 js银行家算法

首先问一下round(0.825,2) 返回的结果,大家猜一猜,

首先SQL server 返回的是 0.83

js的返回结果 是0.83,code 如下:

  var b = 0.825;
        alert(Math.round(b * 100) / 100);
其实js中可以 直接用toFixed函数的,

  var b = 0.825;
        alert(b.toFixed(2));

这样也返回0.83


可是C# 返回的是0.82

      

这里并不是我们期望的0.83, 为什么了? 其实C#中的Math.Round()并不是使用的"四舍五入"法 而是四舍六入五取偶(银行家算法Banker's rounding),若需要舍入到的位的后面"小于5"或"大于5"的话,按通常意义的四舍五入处理.若"若需要舍入到的位的后面"等于5",则要看舍入后末位为偶数还是奇数.

Math.Round(1.25, 1) = 1.2 因为5前面是2,为偶数,所以把5舍去不进位
Math.Round(1.35, 1) = 1.4 因为5前面是3,为奇数,所以进位.

为了解决这个 问题,微软提供了其他的API

Round(Decimal, MidpointRounding)
Round(Double, MidpointRounding)
Round(Decimal, Int32, MidpointRounding)
Round(Double, Int32, MidpointRounding)

网上有人说 这个API 计算小数时有问题, 其实我们可以自己实现Round 函数,

 public static decimal Round(decimal d,int decimals)  
        {  
            decimal tenPow = Convert.ToDecimal(Math.Pow(10, decimals)); 
            decimal scrD = d * tenPow + 0.5m; 
            return (Convert.ToDecimal(Math.Floor(Convert.ToDouble(scrD))) / tenPow); 
        } 

或者如下,

  public static decimal Round(decimal d, int decimals)
        {
            d = d + 0.000000000000001m;
            return Decimal.Round(d, decimals);
        } 


如果我们现在需要 用js 来实现 银行家算法,又该怎么实现了

Number.prototype.round = function (len) {
    var old = this;
    var a1 = Math.pow(10, len) * old;
    a1 = Math.round(a1);
    var oldstr = old.toString()
    var start = oldstr.indexOf(".");
    if (start > 0 && oldstr.split(".")[1].length == len + 1) {
        if (oldstr.substr(start + len + 1, 1) == 5) {
            var flagval = oldstr.substr(start + len, 1) - 0;
            if (flagval % 2 == 0) {
                a1 = a1 - 1;
            }
        }
    }
    var b1 = a1 / Math.pow(10, len);
    return b1;
}
Number.prototype.oldtoFixed = Number.prototype.toFixed;
Number.prototype.toFixed = function (len) {
    var old = this;
    var oldstr = old.toString()
    var start = oldstr.indexOf(".");
    if (len == 2 && start > 0 && oldstr.split(".")[1].length == 3) {
        return this.round(len);
    }
    else {
        return this.oldtoFixed(len);
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值