亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

JS中toFixed()方法四舍五入的精度問題詳解

 更新時間:2021年10月12日 10:41:30   作者:橙某人  
最近在做項目的時候,遇到了有四舍五入保留兩位的需求,當(dāng)時不假思索的直接使用了js原生的toFixed方法,結(jié)果出現(xiàn)了問題,這篇文章主要給大家介紹了關(guān)于JS中toFixed()方法四舍五入精度問題的相關(guān)資料,需要的朋友可以參考下

踩的坑

最近工作中,在計算一個商品的折扣價格,有時候總是出現(xiàn)價格會有一分錢的差異,涉及錢的問題都是比較敏感的,經(jīng)過排查,最后發(fā)現(xiàn)竟然是 JS 原生的 toFixed 方法的問題。

好家伙,這都啥規(guī)律啊。。。(⊙o⊙)

填坑方法

先不著急去探究其中的問題,既然發(fā)現(xiàn)了問題,那就先把 Bug 修復(fù)了先,原生方法用不了,就自己寫一個唄,還不是分分鐘的事情,哈哈哈!

/**
 * 保留小數(shù)點幾位數(shù), 自動補零, 四舍五入
 * @param num: 數(shù)值
 * @param digit: 小數(shù)點后位數(shù)
 * @returns string
 */ 
function myFixed(num, digit) {
  if(Object.is(parseFloat(num), NaN)) {
    return console.log(`傳入的值:${num}不是一個數(shù)字`);
  }
  num = parseFloat(num);
  return (Math.round((num + Number.EPSILON) * Math.pow(10, digit)) / Math.pow(10, digit)).toFixed(digit);
}

什么樣的坑?

好了,既然 Bug 解決完了,下面我們就來探索一下 toFixed 其中的奧秘。

呃...首先,Em...百度一下吧,面向百度編程工程師,果然一查大把結(jié)果,看來是個經(jīng)典問題了。

經(jīng)過一番了解得知,原來是 toFixed 方法采用的四舍五入,并不是我們理解的字面上的四舍五入。而 toFixed 方法它是采用一種詭異的方法 "四舍六入五取偶" ,也叫銀行家算法,這是什么個意思呢?

完整說法:"四舍六入五考慮,五后非零就進一,五后為零看奇偶,五前為偶應(yīng)舍去,五前為奇要進一"。

大概意思是:當(dāng)舍去位的數(shù)值 ≤4 時舍去,當(dāng)它 ≥6 時加上,可當(dāng)它 =5 時,則根據(jù) 5 后面的數(shù)字來定;當(dāng) 5 后有非零數(shù)字時,舍 5 入 1;當(dāng) 5 后無有效數(shù)字時,需要再分兩種情況:5 前為偶數(shù),舍 5 不進;5 前為奇數(shù),舍 5 入 1 。

根據(jù)這個規(guī)則,我在瀏覽器上又跑了一些測試,但卻還是感覺不對。

// 五前是偶數(shù),沒有舍去?
console.log(1.00000065.toFixed(7)); // 1.0000007 錯誤
console.log(1.000000065.toFixed(8)); // 1.00000007 錯誤
// 五前是奇數(shù),沒有進一?
console.log(1.00000015.toFixed(7)); // 1.0000001 錯誤
console.log(1.000000015.toFixed(8)); // 1.00000001 錯誤

這到底為啥?真是讓人摸不著頭腦。。。(︶︿︶)

再經(jīng)過一番探索,總算是有點收獲了,下面就得來看看 ECMAScript 規(guī)范對該方法的定義了,有時候回歸規(guī)范才是最靠譜的方式。

上圖是關(guān)于整個 toFixed 方法的定義,不過是翻譯后的版本,會有出入但差別不大,也可以點擊上面的鏈接查看原文,我們主要關(guān)注圖中紅框部分,通過公式來計算舍去位數(shù)值。

我們下面兩個來舉個栗子,測試一下。

console.log(1.0000005.toFixed(6)); // 1.000001 正確
console.log(1.00000005.toFixed(7)); // 1.0000000 錯誤  

首先,根據(jù)紅框的條件,x<10^21,1.0000005 與 1.00000005 都是小于 10^21 的,所以我們直接可以使用公式 n / 10^ - x 來玩耍。

我們先用 x=1.0000005 代入公式來看看情況:

// 假設(shè)n1
var n1 = 1000000;
var x = 1.0000005;
var f = 6;
console.log((n1 / Math.pow(10, f) - x)); // -5.00000000069889e-7

// 假設(shè)n2
var n2 = 1000001;
var x = 1.0000005;
var f = 6;
console.log((n2 / Math.pow(10, f) - x)); // 4.999999998478444e-7

由結(jié)果可知,當(dāng) n1=1000001 時,得到的結(jié)果取最接近 0 的值,故:

console.log(1.0000005.toFixed(6)); // 1.000001 正確

再來試試當(dāng) x=1.00000005 代入公式:

// 假設(shè)n1
var n1 = 10000000;
var x = 1.00000005;
var f = 7;
console.log((n1 / Math.pow(10,f) - x)); // -4.9999999918171056e-8

// 假設(shè)n2
var n2 = 10000001;
var x = 1.00000005;
var f = 7;
console.log((n2 / Math.pow(10,f) - x)); // 5.000000014021566e-8

由結(jié)果可知,當(dāng) n2=10000001 時,得到的結(jié)果取最接近 0 的值,故:

console.log(1.00000005.toFixed(7)); // 1.0000000 錯誤

哎...寫到這里才發(fā)現(xiàn)給自己挖了一個大坑,干嘛要搞那么多零,自己都數(shù)暈圈了。。。

總的來說,上面例子就是教你如何通過規(guī)范定義的公式計算出結(jié)果而已,如果你看得懂規(guī)范,那么直接去代入也是沒有問題的。

總結(jié)

到此這篇關(guān)于JS中toFixed()方法四舍五入精度問題的文章就介紹到這了,更多相關(guān)JS toFixed()四舍五入精度問題內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 淺談Webpack 是如何加載模塊的

    淺談Webpack 是如何加載模塊的

    這篇文章主要介紹了Webpack 是如何加載模塊的,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-05-05
  • 詳解ECMAScript2019/ES10新屬性

    詳解ECMAScript2019/ES10新屬性

    這篇文章主要介紹了詳解ECMAScript2019/ES10新屬性,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • JS實現(xiàn)對json對象排序并刪除id相同項功能示例

    JS實現(xiàn)對json對象排序并刪除id相同項功能示例

    這篇文章主要介紹了JS實現(xiàn)對json對象排序并刪除id相同項功能,涉及javascript針對json格式數(shù)據(jù)的遍歷、運算、判斷、添加、刪除等相關(guān)操作技巧,需要的朋友可以參考下
    2018-04-04
  • js的alert樣式如何更改如背景顏色

    js的alert樣式如何更改如背景顏色

    如何更改js的alert樣式如:彈出對話框時的背景顏色、背景透明等等,下面有效果圖,感興趣的朋友可以學(xué)習(xí)下
    2014-01-01
  • 關(guān)于ES6新特性最常用的知識點匯總

    關(guān)于ES6新特性最常用的知識點匯總

    日常開發(fā)中寫的 JavaScript 代碼,會用到ES6的部分新特性,所以下面這篇文章主要給大家介紹了關(guān)于ES6新特性最常用的知識點,文章總結(jié)的非常全面,需要的朋友可以參考下
    2021-11-11
  • 通過javascript實現(xiàn)段落的收縮與展開

    通過javascript實現(xiàn)段落的收縮與展開

    這篇文章主要介紹了通過javascript實現(xiàn)段落的收縮與展開,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-06-06
  • JavaScript 使用技巧精萃(.net html

    JavaScript 使用技巧精萃(.net html

    下面是一些編程語言中,經(jīng)常需要用到j(luò)s驗證的一些代碼加入方法大家可以參考下。
    2009-04-04
  • 最新評論