Skip to content

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 在处理大整数时的精度损失问题

小小棱镜,无限可能