zoukankan      html  css  js  c++  java
  • js toFixed() 四舍五入后并不是你期望的结果

    小学的时候学数学就知道有一种叫四舍五入的计算方式,就是对于小数位数的取舍,逢五进一,比如1.225 取两位小数后就是1.23。在前端开发中自己也少不了这样的计算,js也提供了相关的方法--toFixed(n) , 乍一看,还是非常方便的,既然有现成的那就顺序成章,‘肆无忌惮’用了,可是,用着用着就会发现,并没有那方便。因为经常会有你意想不到的问题。比如:1.005.toFixed(2) = 1.00,what? 不应该是1.01吗? 显然,这已经不是五入了,而是五舍了。这可怎么整呢?请看如下代码:

    let Num = Number
    Num.prototype.toFixed = function (d) {
        let s = this + ''
        if (!d) d = 0
        if (s.indexOf('.') === -1) s += '.'
        s += new Array(d + 1).join('0')
        if (new RegExp('^(-|\+)?(\d+(\.\d{0,' + (d + 1) + '})?)\d*$').test(s)) {
          let ss = '0' + RegExp.$2
          let pm = RegExp.$1
          let a = RegExp.$3.length
          let b = true
            if (a === d + 2) {
                a = ss.match(/d/g)
                if (parseInt(a[a.length - 1]) > 4) {
                    for (let i = a.length - 2; i >= 0; i--) {
                        a[i] = parseInt(a[i]) + 1
                        if (a[i] === 10) {
                            a[i] = 0
                            b = i !== 1
                        } else break
                    }
                }
                ss = a.join('').replace(new RegExp('(\d+)(\d{' + d + '})\d$'), '$1.$2')
            }
            if (b) ss = ss.substr(1)
            return (pm + ss).replace(/.$/, '')
        }
        return this + ''
    }
    

      因为toFixed() 方法可把 Number 四舍五入为指定小数位数的数字。例如将数据Num保留2位小数,则表示为:toFixed(Num);但是其四舍五入的规则与数学中的规则不同,使用的是银行家舍入规则,银行家舍入:所谓银行家舍入法,其实质是一种四舍六入五取偶(又称四舍六入五留双)法。具体规则如下:简单来说就是:四舍六入五考虑,五后非零就进一,五后为零看奇偶,五前为偶应舍去,五前为奇要进一。

      经测试发现,在chorme下面,并没有完全遵守这个规则,尤其是5的后面没有数字的时候,不是这么判断的,如下:

    var b = 1.335
    
    b.toFixed(2)
    
    "1.33"
    
    var b = 1.345
    
    b.toFixed(2)
    
    "1.34"
    
    var b = 1.355
    
    b.toFixed(2)
    
    "1.35"
    
    var b = 1.365
    
    b.toFixed(2)
    
    "1.36"
    
    var b = 1.375
    
    b.toFixed(2)
    
    "1.38"
    
    var b = 1.385
    
    b.toFixed(2)
    
    "1.39"
  • 相关阅读:
    grub menu from pygrub
    Unix调试的瑞士军刀:lsof
    Quantum & r2q
    Linux TC基于CBQ队列的流量管理范例
    hfsc
    用bash做个tcp客户端
    [转]HFSC Scheduling with Linux
    [转]如何判断 Linux 是否运行在虚拟机上
    TSO
    使用VS2008进行WEB负载测试
  • 原文地址:https://www.cnblogs.com/garfieldzhong/p/11254610.html
Copyright © 2011-2022 走看看