在一次开发列表编辑页面时发现一个诡异的问题,列表展现的数据和回显的数据不同,第一反应是接口出错了,查看了一下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
复制代码