zoukankan      html  css  js  c++  java
  • 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);
        }
    }
  • 相关阅读:
    拖动图片浏览的程序(VB6)
    Nod32升级服务器(转)
    看了部电影"蝴蝶效应"
    BackgroundWorker的替代者! (转)
    为什么我爱黑莓8700
    什么是反射(.NET)[转]
    使用VS2008编写了第一个WM5短信发送程序!
    不睡觉果然还是不行。
    关于net2.0里面新出现的类backgroundworker的应用 (转)
    是男人就打5000分!(C#)
  • 原文地址:https://www.cnblogs.com/majiang/p/5020521.html
Copyright © 2011-2022 走看看