<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          toFixed 函數(shù)引起的 bug

          共 2548字,需瀏覽 6分鐘

           ·

          2021-05-06 18:48

          轉(zhuǎn)自:掘金 -  紅塵煉心

          https://juejin.cn/post/6927215610552123406

          前言

          某天,客服告訴我,有客戶投訴,說賬單金額數(shù)據(jù)統(tǒng)計不對,同時測試也反饋在IE11瀏覽器上又是正確的。

          經(jīng)過排查發(fā)現(xiàn)是toFixed()引起的。

          緣由

          來看一下toFixed()在chrome、火狐、IE下的不同表現(xiàn)。

          chrome:

          火狐:

          IE:

          可以看到toFixed()的四舍五入在chrome、火狐上并不準(zhǔn)確。

          toFixed()在chrome、火狐上也并不是網(wǎng)上所說的用銀行家舍入法來進(jìn)行四舍五入的。

          銀行家舍入法的規(guī)則是“四舍六入五考慮,五后非零就進(jìn)一,五后為零看奇偶,五前為偶應(yīng)舍去,五前為奇要進(jìn)一”。

          例如銀行家舍入法在 (2.55).toFixed(1) = 2.5、(3.55).toFixed(1) = 3.5 上就不符合了。

          那為什么會這樣呢,要從toFixed的定義說起,來看ecmascript 規(guī)范對toFixed的表述:

          按上圖中的步驟來演示一下(2.55).toFixed(1) = 2.5的處理過程。

          x為2.55,小于,f為1,要使準(zhǔn)確的數(shù)學(xué)值盡可能接近零,取n為25和n為26,

          可以看到最接近零的應(yīng)該是 -0.04999... ,故n為25,那么m為25,k為2, 為1,故a為2,則b為5,所以(2.55).toFixed(1)的結(jié)果為2.5。可以看出(2.55).toFixed(1)的結(jié)果是2.5而不是2.6,是... 引起,而為什么不等于0.5,其原因和不等0.3是一樣,可以看我這篇專欄《非科班前端人的一道送命題:0.1+0.2 等于 0.3 嗎?》。

          但是在IE瀏覽器中,執(zhí)行 和  的結(jié)果和在chrome和火狐瀏覽器中執(zhí)行的結(jié)果是一樣。這里只能推斷IE瀏覽器中定義的toFixed不符合ecmascript 規(guī)范,具體原因目前也不清楚,如果知道的同學(xué)可以在評論中留言,謝謝。


          解決


          假設(shè)要四舍五入的數(shù)字為number,要保留n位小數(shù),可以先用 ,然后用 Math.round()取整,最后在除去,間接實(shí)現(xiàn)四舍五入。另外toFixed()還有個自動補(bǔ)零的功能,也要實(shí)現(xiàn)一下,故下面簡單封裝了一個toFixed方法來實(shí)現(xiàn)四舍五入。

          function toFixed(number, m) {
              if (typeof number !== 'number') {
                  throw new Error("number不是數(shù)字");
              }
              let result = Math.round(Math.pow(10, m) * number) / Math.pow(10, m);
              result = String(result);
              if (result.indexOf(".") == -1) {
                  if(m != 0){
                      result += ".";
                      result += new Array(m + 1).join('0');
                  }
              } else {
                  let arr = result.split('.');
                  if (arr[1].length < m) {
                      arr[1] += new Array(m - arr[1].length + 1).join('0')
                  }
                  result = arr.join('.')
              }
              return result
          }


          - EOF -

          瀏覽 68
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲黄色毛片 | 思思热精品在线视频 | 草青青成人 | 特级西西444www精品视频 | 亚洲国产精品波多野结衣 |