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)

  • 相关阅读:
    C# 窗体间传值方法大汇总(转)
    STM32 配置PC13~PC15
    STM32的USART发送数据时如何使用TXE和TC标志
    STM32_NVIC寄存器详解
    protel99se 问题汇总(不定期更新)
    STM32串口IAP实验笔记
    Keil MDK下如何设置非零初始化变量(复位后变量值不丢失)
    STM32定时器配置(TIM1-TIM8)高级定时器+普通定时器,定时计数模式下总结
    帮助类-AD域操作
    GitHub贡献第一的公司是谁?微软开源软件列表
  • 原文地址:https://www.cnblogs.com/rencoo/p/11891402.html
Copyright © 2011-2022 走看看