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);
        }
    }
    View Code
  • 相关阅读:
    【校招面试 之 C/C++】第23题 C++ STL(五)之Set
    Cannot create an instance of OLE DB provider “OraOLEDB.Oracle” for linked server "xxxxxxx".
    Redhat Linux安装JDK 1.7
    ORA-10635: Invalid segment or tablespace type
    Symantec Backup Exec 2012 Agent for Linux 卸载
    Symantec Backup Exec 2012 Agent For Linux安装
    You must use the Role Management Tool to install or configure Microsoft .NET Framework 3.5 SP1
    YourSQLDba介绍
    PL/SQL重新编译包无反应
    MS SQL 监控数据/日志文件增长
  • 原文地址:https://www.cnblogs.com/tonykan/p/6244956.html
Copyright © 2011-2022 走看看