在日常一些需求中,總會遇到一些需要前端進行手動計算的場景,那麼這裡需要優先考慮的則是數字精度問題!具體請看下麵截圖 如圖所示,在JavaScript進行浮點型數據計算當中,會出現計算結果“不正確”的現象。 我們知道浮點型數據類型主要有:單精度float、雙精度double。 浮點型簡單來說就是表示帶 ...
在日常一些需求中,總會遇到一些需要前端進行手動計算的場景,那麼這裡需要優先考慮的則是數字精度問題!具體請看下麵截圖
如圖所示,在JavaScript進行浮點型數據計算當中,會出現計算結果“不正確”的現象。
我們知道浮點型數據類型主要有:單精度float、雙精度double。
浮點型簡單來說就是表示帶有小數的數據,而恰恰小數點可以在相應的二進位的不同位置浮動,可能是因為這樣就被定義成浮點型了。(不得不佩服這文化程度,定義個數據名稱都這麼有深度~)
但是!!!
JavaScript 存儲小數和其它語言如 Java 和 Python 都不同,JavaScript 中所有數字包括整數和小數都只有一種類型 即 Number類型 它的實現遵循 IEEE 754 標準,IEEE 754 標準的內容都有什麼,這個咱不用管,我們只需要記住以下一點:
javascript以64位雙精度浮點數存儲所有Number類型值,即電腦最多存儲64位二進位數。
對於double型數據(雙精度浮點數),其長度是8個位元組(大小),右邊52位用來表示小數點後面的數字,中間11位表示e(exponent)小數點移動的位數,左邊一位用來表示正負。如圖所示:
只要知道了這一點,那我們就可以對症下藥(解決問題):
解決方案 ①
Number(parseFloat(20.24*100).toPrecision(16))
存儲二進位時小數點的偏移量最大為52位,最多可表示的十進位為9007199254740992,對應科學計數尾數是 9.007199254740992,這也是 JavaScript 最多能表示的精度。它的長度是 16,所以可以使用 toPrecision(16) 來做精度運算。
通過先轉為浮點型計算,然後做精度運算後再轉為Number類型即可。
解決方案 ②
通過引入number-precision
進行計算,步驟如下:
- Install
npm install number-precision --save
- Methods
NP.strip(num) // strip a number to nearest right number
NP.plus(num1, num2, num3, ...) // addition, num + num2 + num3, two numbers is required at least.
NP.minus(num1, num2, num3, ...) // subtraction, num1 - num2 - num3
NP.times(num1, num2, num3, ...) // multiplication, num1 * num2 * num3
NP.divide(num1, num2, num3, ...) // division, num1 / num2 / num3
NP.round(num, ratio) // round a number based on ratio
- Usage
import NP from 'number-precision'
NP.strip(0.09999999999999998); // = 0.1
NP.plus(0.1, 0.2); // = 0.3, not 0.30000000000000004
NP.minus(1.0, 0.9); // = 0.1, not 0.09999999999999998
NP.times(3, 0.3); // = 0.9, not 0.8999999999999999
NP.divide(1.21, 1.1); // = 1.1, not 1.0999999999999999
NP.round(0.105, 2); // = 0.11, not 0.1
更多解決方案敬請關註後續更新,希望對您有幫助~
作者:京東零售 黃巨集峰
來源:京東雲開發者社區 轉載請註明來源