一個 double 型別精度問題導致的 Bug
阿新 • • 發佈:2019-01-09
在寫 Weex 的時候,遇到一個 Bug —— 顯示的訂單 ID 不對,和 API 測試平臺獲取的資料不一致。首先懷疑的是取錯欄位了,認真檢查了一下,不是這個原因。然後懷疑的是 Native 網路請求模組 JsonString 轉 Model 的時候出錯了,Debug 了一下發現網路請求的結果解析成的 Model 裡面的 ID 是對的,也不是這個原因。那問題就一定是出在 ID 從 Native 傳遞到 JS 環境這個環節。懷疑是數字太大,超出了 JS 的能表示的最大值。查了 JS 的文件1、文件2,JS 裡面所有的數字都用 double 儲存,double 的格式是這樣的:
這樣的話,表示整數的話超過2^53 可能會損失精度,(超過2^53 , 就是1 ~ 2^53 乘以 2 、 4、 8 這樣表示了,沒法精確了),小數的話除非是2^-n 這種,否則無法精確表示( 浮點小數精度的問題還付出過生命的代價)。
在 Chrome Console 裡面試了一下,果然是這樣,(只不過不是超過了能表示的最大值,而是超過了能精確表示的最大值)。
這個 Bug 告訴我們,ID 這種最好服務端返回給我 String 型別,用 double 要小心點,整數超過一定範圍可能就沒法精確了,小數加減乘除可能會有誤差(十進位制小數與二進位制小數相互轉換產生的誤差),要小心點。