Long类型数据前端精度丢失

问题描述

后端把Long类型的数据传给前端,前端可能会出现精度丢失的情况。例如:201511200001725439这样一个Long类型的整数,传给前端后会变成201511200001725440

相关概念

javaScript 的最大安全值:Number.MAX_SAFE_INTEGER 是一个值为 9007199254740991 的常量。因为 javaScript的数字存储使用了 IEEE 754 中规定的 双精度浮点数 数据类型,而这一数据类型能够安全存储 -(2^53 - 1)2^53 - 1 之间的数值(包含边界值)。// 也即 -(Math.pow(2, 53) - 1) 到 (Math.pow(2, 53) - 1),即 -9007199254740991 到 9007199254740991之间的数值(包含边界值)

这里安全存储的意思是指能够准确区分两个不相同的值,例如

Number.MAX_SAEF_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2 将得到 true 的结果,而这在数学上是错误的

下图可以看出,输入的值超出安全值,可能会被js自动转化

imgimg

另外,javaScript 的最大值: Number.MAX_VALUE 其值为 1.7976931348623157e+308,代表js可表示的最大值,使用时可用来判断某个值是否超出了 js 可表示的最大值

场景还原

使用 nodejs 起一个服务, 然后传给前端一个Long类型的数值

const http = require('http')

const onRequest = function (request, response{
    console.log('---Request received---')
    response.writeHead(200, {
        'Content-Type''application/json'
    })
    var data = {
        number201511200001725439 // (*)
    }
    response.end(JSON.stringify(data))
}

const server = http.createServer(onRequest)
server.listen(3000'127.0.0.1')
console.log('Server started on localhost port 3000')

访问 localhost:3000

{
    "number"201511200001725440
}

发现我们前端得到的数值和后端原本设置的数值不一样

解决方案一

在后台将这个Long类型的字段转换成String类型的,风险比较大

const http = require('http')

const onRequest = function (request, response{
    console.log('---Request received---')
    response.writeHead(200, {
        'Content-Type''application/json'
    })
    var data = {
        number'201511200001725439' // (*) // string
    }
    response.end(JSON.stringify(data))
}

const server = http.createServer(onRequest)
server.listen(3000'127.0.0.1')
console.log('Server started on localhost port 3000')

再次访问

{
    "number""201511200001725439"
}

这回发现前后端的数据完全一致,没有出现精度丢失

解决方案二

使用 fastjson 的提供的注解@JSONField(serializeUsing= ToStringSerializer.class)

原文地址:https://www.cnblogs.com/rencoo/p/11891402.html