小學的時候學數學就知道有一種叫四舍五入的計算方式,就是對於小數位數的取舍,逢五進一,比如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"