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)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM