Number精度问题
概要
提示:Number精度丢失
在开发过程中,我遇到了一个问题:通过请求接口返回的Number
类型数据(大约有16位)与数据库存储的数据不一致,并且每次请求时会莫名奇妙地变大或变小。为了解决这个问题,我最初的解决方案是让后端将该Number
转换成String
类型进行处理,但你并不清楚为什么这个值会发生变化。
技术细节
提示:具体实现
首先看一道题,他的输出结果是多少
javascript
// 这段代码会输出多少次 loop?
var START = 2 ** 53
var END = START + 100
for (var i = START; i < END; i++) {
console.log('loop')
}
答案是:不可预测
原因是在 JavaScript 中,当超出安全整数范围时,数字会被转换为双精度浮点数。由于浮点数的精度有限,而 START 的值非常大,超过了浮点数的表示范围,所以它无法准确表示该值
什么是安全整数范围?2 的 53 次方减 1
|| Number.MAX_SAFE_INTAGER
就是能表达出的最大范围
javascript
2 ** 53 === 9007199254740992
// 最大的安全整数,js里最大的不损失精度的整数
Number.MAX_SAFE_INTAGER === 9007199254740991
2 ** 53 - 1 === 9007199254740991
小结
提示:精度问题
一次偶然的请求接口,接口返回的16位Number精度丢失,遇到类似的问题,可以进行转String类型避免
换句话可以这么说。如果你遇到Number精度丢失的问题,可以考虑将数字转换为字符串类型进行处理。这样可以避免 JavaScript 在处理大整数时的精度损失问题