toFixed和Math.round既不是四舍五入也不是銀行家舍入法
toFixed 介紹
JavaScript 的 toFixed 方法使用定點表示法來格式化一個數(shù)值,數(shù)字.toFixed(要保留幾位小數(shù)),參數(shù)為小數(shù)點后數(shù)字的個數(shù),介于 0 到 20(包括)之間,默認(rèn) 0,返回值為使用定點表示法表示給定數(shù)字的字符串,該數(shù)值在必要時進行四舍五入,不足位數(shù)時會直接用 0 來填充小數(shù)部分。
需要注意
只能用于 Number 數(shù)值類型數(shù)據(jù)上
返回值是 String 字符串,但是負(fù)數(shù)如果不加括號因為操作符優(yōu)先級會返回 Number 數(shù)值
四舍五入規(guī)則并不是我們常見的數(shù)學(xué)上的四舍五入法,而是使用的類似銀行家舍入法,其實也和銀行家舍入法不太一樣
Math.round
Math.round() 函數(shù)返回一個數(shù)字四舍五入后最接近的整數(shù),注意這個同樣不是真正意義上的四舍五入,也和銀行家舍入法不太一樣:
如果參數(shù)的小數(shù)部分大于 0.5,則舍入到相鄰的絕對值更大的整數(shù)
如果參數(shù)的小數(shù)部分小于 0.5,則舍入到相鄰的絕對值更小的整數(shù)
如果參數(shù)的小數(shù)部分恰好等于 0.5,則舍入到相鄰的在正無窮(+∞)方向上的整數(shù)
銀行家舍入法
按概率論 0、1、2、3、4、5、6、7、8、9 隨機分布出現(xiàn),傳統(tǒng)的四舍五入讓銀行虧錢,因為把5都往大了算。于是就有了銀行家舍入(banker's rounding)的算法,規(guī)則四舍六入五取偶:
4及以下直接舍去(和四舍五入一樣)
大于等于6時,進位后舍去(和四舍五入一樣)
5的情況比較復(fù)雜:① 5后面還有數(shù)字,則進位后舍去;② 5后面沒有數(shù)字了,那么如果5前面的一個數(shù)字是奇數(shù),則進1,若5前面的數(shù)字是偶數(shù)則直接舍去 5

雖然這種舍入法叫“銀行家舍入”,但實際上和銀行關(guān)系不大。我國金融系統(tǒng)的大部分算法就是用四舍五入,國際上歐盟委員會對換匯時的舍入規(guī)定也是我們常見的四舍五入。
真正廣泛采用銀行家舍入法的,是需要更小誤差的科學(xué)和計算機系統(tǒng),因此銀行家舍入法也叫統(tǒng)計學(xué)家舍入(statistician's rounding)、無偏舍入(unbiased rounding)?,F(xiàn)在大部分編程軟件的默認(rèn)舍入都是銀行家舍入法,比如 c/c++、javascript、php、go,英特爾處理器用的也是銀行家舍入。
在瀏覽器或者node環(huán)境中按照銀行家的舍入規(guī)則去測試 toFixed 和 Math.round,發(fā)現(xiàn)當(dāng)5后面沒有數(shù)字時,并不是按照銀行家舍入法的奇近偶舍,但網(wǎng)上有很多說這兩貨是用的銀行家舍入法,注意踩坑,項目中實際運算還是用第三方計算庫或者讓后端計算比較好。
參考:
Number.prototype.toFixed
Math.round