zoukankan      html  css  js  c++  java
  • 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)

  • 相关阅读:
    .netCore+Vue 搭建的简捷开发框架 (5)
    .netCore+Vue 搭建的简捷开发框架 (4)--NetCore 基础 -2
    Vue 学习笔记
    .netCore+Vue 搭建的简捷开发框架 (4)--NetCore 基础
    .netCore+Vue 搭建的简捷开发框架 (3)-- Services层实现
    .netCore+Vue 搭建的简捷开发框架 (2)--仓储层实现和EFCore 的使用
    .netCore+Vue 搭建的简捷开发框架
    在线.net C#和vb.net 语言互转
    VB.net 通过句柄操作其他窗口
    vb.net 多线程爬虫抓取免费代理IP
  • 原文地址:https://www.cnblogs.com/rencoo/p/11891402.html
Copyright © 2011-2022 走看看