JS 遵循IEEE 754規范,采用雙精度存儲(double precision),占用 64 bit。
精度缺失:
精度缺失最典型例子:
0.1+0.2 != 0.3(true);0.1+0.2 = 0.30000000000000004
造成原因,浮點數的表示:
浮點數:0.1 >> 0.0001 1001 1001 1001…(1001無限循環)0.2 >> 0.0011 0011 0011 0011…(0011無限循環)
0.1,0.2的二進制表示的是一個無限循環小數,目前 JS 采用的是浮點數標准需要對這種無限循環的二進制進行截取,從而導致了精度丟失,造成了0.1不再是0.1,截取之后0.1變成了 0.100…001,0.2變成了0.200…002,所以兩者相加的數大於0.3。
這個網站統計了不同語言計算0.1+0.2的結果:http://0.30000000000000004.com/ (可以作為學習了解一下)
解決方案:第三方庫有math.js、decimal.js等。手寫方案通常通過轉化整數進行計算后還原。
最大安全整數:
JS 的最大和最小安全整數值:
最大值:Number.MAX_SAFE_INTEGER // 9007199254740991 ;最小值:Number.MIN_SAFE_INTEGER) //-9007199254740991
當超出這個值范圍之后,數字值將不再准確。
典型案例:在后端發送給前端數據的時候,前端通過Json.parse()進行數據處理的時候,數據值不在范圍內就會出現數據錯誤的問題。
造成原因:也是由於雙精度浮點數導致最大數為2^53 - 1
解決方案:第三方庫有bignum、bigint等。手寫方案推薦該類字段做字符串處理。
總結:
從上面兩個例子看出,問題的根源其實是關於IEEE 754規范的,這個問題並不只是在Javascript中才會出現,任何使用二進制浮點數的編程語言都會有這個問題。
要理解出的問題和自擬方案的伙伴可以去查一查了解下IEEE 754標准規范,才能從本質上去看透很多東西。只是單純尋找解決方案不妨試試推薦的第三方庫吧。