js計算結果不精確問題解決--math.js的使用


最近在做訂單相關的一個功能,涉及到金額的計算,有人建議,將計算全部拋給后端來做吧,前端就不需要再維護一套算法了,話說的在理,但是呢,想想用戶體驗,單價*數量=金額,當用戶改變一個數量時,用戶都口算出來金額了,然而頁面還在請求的loading中,這也太.......

於是乎,我決定前端也維護一套算法,給用戶最快的響應.頁面大致如下:

正常來說,這完全不是個事,很快就全部按要求實現 了,然而,測試過程中,發現了下圖:

什么?    0.14*100=14.0000000000000002     ???

開發這么多年,真的第一次遇到,於是乎開始了各種測試,各種查閱,原來是這樣啊:
js計算時,會將十進制轉換成二進制,再進行計算,但有些小數轉換成二進制時候,出現了無限循環,由於位數有限,所以就出現了截取,所以就導致了再轉化成十進制后結果的不精確.所以就出現了: 0.1+0.2 !== 0.3

不說這些廢話了,直接來解決方案:

math.js 是一款功能強大,使用靈活的數學庫。不過此處我只需使用加減乘除等簡單的方法,需要更多者可以查閱官網


1,引入第三方的js庫, math.js,

官網:http://mathjs.org/

math.js的下載地址是:
https://cdnjs.cloudflare.com/ajax/libs/mathjs/5.0.0/math.js。


2,在程序入口處統一配置以下math.js,

 //統一配置math.js
    math.config({
        number: 'BigNumber',  
        // 'number' (default), 
        precision: 20         
    });

3,使用mathjs里的運算方式改寫計算公式:比如,以前的的金額計算如下:

  item.amount = item.listPrice * item.orderNum;

     改寫之后為:

 //使用math.js轉換數據類型
 item.listPrice = math.bignumber(item.listPrice) ;                    

 //計算金額:金額=列表價*數量
 var amountOfBigNumber = item.listPrice * item.orderNum;

 //轉換結果類型,提取數字(不轉的話,得到的是對象)
item.amount = math.number(amountOfBigNumber);               

       這樣就不會出現誤差,結果就能正常了,即  0.14 * 100 = 14 !     

注:常用的幾個運算方法是:

運算 方法名 參數 備注
math.add(a,b,c,...)
參數個數>=2 得到幾個數字的和
math.subtract(a,b)
參數個數=2 得到 a-b 的結果, 不可連減
math.multiply(a,b,c,...) 參數個數>=2 得幾個參數的乘積
math.divide(a,b)
參數個數=2 得到 a/b 的結果 ,不可連除
轉換為bigNumber類型
math.bignumber(a)
  浮點數,進行運算時,轉換成bigNumber才能保證得到精確的結果
轉換為數字類型
math.number(a)
  bignumber為對象,此方法可以獲取對象中的數字部分

 

另外,還有以款比較強大的數學庫,BigNumber.js,同樣能解決我們的問題,有興趣者可以研究下

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM