一文解決前端JS小數運算精度問題
前言
在做項目的時候,前端需要在表格的底部做一個匯總的功能,在采用reduce對當前屬性所有值匯總時,發(fā)現匯總結果存在好長的小數位,本以為后端的數據就存在精度這么小的數據,后來,檢查發(fā)現后端精度只有三位小數,但前端計算結果為什么會這樣呢?
JS存在精度問題
在控制臺可以試一下 0.1 + 0.2 的結果是0.30000000000000004 js的運算下 0.1 + 0.2 != 0.3
由于計算機在存儲和計算數字的時候,使用的是二進制形式,有些十進制數據再轉換成二進制時,無法精確表示。
JS在數字運算的時候,當存在浮點數的運算時,就有可能會出現精度誤差,有些小數無法用二進制精確表示。
JavaScript采用的是雙精度(64位)浮點運算規(guī)則,遵循的是IEEE二進制浮點數算法標準。其中有1位用作符號位,11位為階碼,尾數有52位。有興趣詳細了解的可以查閱相關資料。
比如 十進制0.1 -> 二進制表示為0.0001 1001 1001 1001...(1100循環(huán)) 十進制0.2 -> 二進制表示為0.0011 0011 0011 0011...(0011循環(huán)) EEE 754 標準的 64 位雙精度浮點數的小數部分最多支持53位二進制位,所以兩者相加之后得到二進制為: 0.1 + 0.2 = 0.0100110011001100110011001100110011001100110011001100 因浮點數小數位的限制而截斷的二進制數字,再轉換為十進制,就成了0.30000000000000004。
解決方案
思路:
- 將小數轉化成整數進行計算,規(guī)避浮點數運算問題。
- 整數的加減乘運算結果不會出現浮點數,不會存在精度問題,但除法會出現浮點數,因此用toFixed()方法截掉無效的小數位。
- 將string轉回number輸出
/** 封裝一個公共方法numberCalculate() 用于浮點數運算 */ //num1 num2傳入兩個值 symbol +-*/符號 numberCalculate(num1: number, num2: number, symbol: string) { var str1 = num1.toString(), str2 = num2.toString(), result, str1Length, str2Length try { //獲取小數點后的精度 str1Length = str1.split('.')[1].length } catch (error) { //解決整數沒有小數點方法 str1Length = 0 } try { str2Length = str2.split('.')[1].length } catch (error) { str2Length = 0 } // 取兩個數的最小精度,即小數點后數字的最大長度 var maxLen = Math.max(str1Length, str2Length) // step將兩個數都轉化為整數至少小數點后移多少位 var step = Math.pow(10, maxLen) switch (symbol) { case "+": // toFixed()根據最小精度截取運算結果 result = ((num1 * step + num2 * step) / step).toFixed(maxLen) break; case "-": result = ((num1 * step - num2 * step) / step).toFixed(maxLen) break; case "*": result = (((num1 * step) * (num2 * step)) / step / step).toFixed(maxLen) break; case "/": result = ((num1 * step) / (num2 * step)).toFixed(maxLen) break; default: break; } // 由于toFixed方法返回結果是字符串,還需要轉回number輸出 return Number(result) }
0.1 + 0.2的計算,就可以調用numberCalculate(0.1,0.2,'+')進行計算了。
以上就是一文解決前端JS小數運算精度問題的詳細內容,更多關于JS小數運算精度的資料請關注腳本之家其它相關文章!
相關文章
解決uni-app報錯Error:?read?EBADF?at?Pipe?.?onStreamRead...
這篇文章主要介紹了uni-app報錯Error:?read?EBADF?at?Pipe?.?onStreamRead...解決方法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-08-08工作中比較實用的JavaScript驗證和數據處理的干貨(經典)
工作中比較實用的JavaScript驗證和數據處理知識經常會用到,下面小編通過查閱相關資料及日常記錄的知識分享到腳本之家平臺,供大家參考2016-08-08