首页IT科技js大数字精度丢失怎么处理(JS踩坑实战之19位数Number型精度丢失问题详析)

js大数字精度丢失怎么处理(JS踩坑实战之19位数Number型精度丢失问题详析)

时间2025-09-15 03:13:10分类IT科技浏览7558
导读:前言 这篇文章主要介绍了JS大坑之19位数的Number型精度丢失问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,有兴趣的朋友们可以一起来学习探讨。...

前言

这篇文章主要介绍了JS大坑之19位数的Number型精度丢失问题                 ,文中通过示例代码介绍的非常详细                          ,对大家的学习或者工作具有一定的参考学习价值         ,有兴趣的朋友们可以一起来学习探讨                 。

最近在实现一个需求的时候                 ,需要接入第三方的接口                         ,先调用A接口         ,A接口返回的数据里         ,有一个taskId                         ,然后再使用这个taskId请求B接口                 ,获取最终需要的数据                          。

后端使用的是node         ,因此最开始使用的是request-promise这个包请求第三方接口                          ,然而在获取A接口返回的taskId之后                 ,调用B接口之后,B接口的响应居然是系统错误!简易代码如下:

const rp = require(request-promise) const { taskId } = await rp(https://xxx.com/A) const options = { method: POST, uri: https://xxx.com/B, body: { taskId }, json: true } const result = await rp(options) // { // "errorcode": "40001", // "message": "系统错误", // "status": "failed" // }

接着我使用postman请求A接口                          ,获取新的taskId                          ,再用新的taskId请求B接口,结果却是正常的!

我在反复检查代码                 ,确认请求的参数都是正常的格式之后                          ,一时陷入了无尽的沉思之中……

发现

在做了几次尝试之后         ,我发现使用node请求得到的taskId最后两位数都是0                 ,即1152921504735848700                         ,而使用postman获取的taskId         ,则是比较正常的是1152921504735848759         ,接着我在node控制台做如下操作:

就是这么一瞬间                         ,顿悟了         。A接口里的taskId是个19位数字                 ,而request-promise在将数据解析成json时         ,导致这个19位的数字丢失了精度                          ,查了下资料                 ,发现js的number类型有个最大安全值,即2的53次方(9007199254740992)                          ,超过这个值就会出现精度丢失的问题                 。

获取正确的响应数据

由于在一开始使用request-promise包                          ,因此获取的taskId是丢失了精度了,因此改用了node原生的http模块发送请求                         。

const req = https.request(https://xxx.com/A, (res) => { res.on(data, (chunk) => { // 由于这里获取到的响应数据是JSON字符串                 ,因此19位的数字只是字符串的一部分                          ,这时获取到的taskId就是正确的数字 console.log(`BODY: ${chunk}`); }); res.on(end, () => { console.log(No more data in response.); }) })

虽然获取到了正常的响应数据         ,但是这是个JSON字符串                 ,接下来还要把这个字符串解析成JSON                         ,但是用JSON.parse()         ,又会引起精度丢失的问题         ,这可真尴尬 ……

如果这个接口是已方可控的                         ,那么就可以把这个19位数的number转成字符串                 ,这样在解析的时候就不会出错了         ,但是由于是第三方接口                          ,因此没法改变         。那么最快的解决方案                 ,就是换种编程语言请求啊         。

最后的解决

好吧,最后还是用了node                          ,不过我用了比较硬核的方案实现                          ,先在获取的JSON字符串中,找到这个19位的数字                 ,然后为它加上引号                          ,这样再用JSON.parse()解析的时候         ,就能保持正常的数值                 ,这样接下的流程就自然通了                         ,代码如下:

let result = {"taskId":1152921504735848759,"status":"CREATED","progress":0.0,"success":true} // JSON.parse(result) 不为19位数补上双引号         ,直接parse时         ,精度丢失                         ,结果如下: // { // taskId: 1152921504735848700, // status: CREATED, // progress: 0, // success: true // } const taskId = result.match(/[0-9]{19}/)[0] // 正则获取19位数字的值 result = result.replace(taskId,`"${taskId}"`) // 补上双引号 const data = JSON.parse(result) // { // taskId: 1152921504735848759, // 解析出来之后是字符串                 ,因此没有丢失精度 // status: CREATED, // progress: 0, // success: true // }

总结

到此这篇关于JS踩坑实战之19位数Number型精度丢失问题的文章就介绍到这了,更多相关JS Number型精度丢失问题内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!

声明:本站所有文章         ,如无特殊说明或标注                          ,均为本站原创发布                         。任何个人或组织                 ,在未征得本站同意时,禁止复制                 、盗用                          、采集         、发布本站内容到任何网站                 、书籍等各类媒体平台                 。如若本站内容侵犯了原著者的合法权益                          ,可联系我们进行处理         。

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
css x(css效果之吸顶效果) 网站权重提升技巧(网站权重提高)