在一次開發列表編輯頁面時發現一個詭異的問題,列表展現的數據和回顯的數據不同,第一反應是接口出錯了,查看了一下ajax請求,好像確實是這樣:ajax
列表請求接口: npm
數據回顯請求接口:瀏覽器
很明顯列表數據和回顯數據不一致,因而就找服務端同窗排查接口問題。服務端同窗反饋從日誌上看是沒問題的,對比他們日誌,發現日誌打印的數據和界面展現的不一致,詭異的事情就這樣發生了。更詭異的是直接在瀏覽器地址欄訪問這個接口,返回的數據和日誌的同樣,和我界面展現的也不一致。bash
看樣子應該是我項目中請求對數據作了處理,回過頭再來看請求的數據,對比發現 driverId 數值,初步定爲是由於數值類型精度丟失。spa
let num = 1001379549335920640
// 1001379549335920600
複製代碼
js數值類型遵循IEEE 754
規範,佔用64位,日誌
s eeeeeee eeee ffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
複製代碼
從左起code
這種表示方法直接致使了精度丟失,當數值沒法用二進制表示時,就會採起0舍1入。cdn
浮點數和大整數都會出現精度丟失。當大整數尾數大於 2^52 = 9007199254740992
時就可能精度丟失blog
9007199254740992 >> 10000000000000...000 // 共計 53 個 0
9007199254740992 + 1 >> 10000000000000...001 // 中間 52 個 0
9007199254740992 + 2 >> 10000000000000...010 // 中間 51 個 0
複製代碼
9007199254740992 + 1 // 丟失
// 9007199254740992
9007199254740992 + 2 // 未丟失
// 9007199254740994
9007199254740992 + 3 // 丟失
// 9007199254740996
9007199254740992 + 4 // 未丟失
// 9007199254740996
複製代碼
// 0.1 + 0.2
(0.1*10 + 0.2*10) / 10 == 0.3 // true
複製代碼