zoukankan      html  css  js  c++  java
  • js处理java后端接口返回long值解析不准确的问题

      在工作中,遇到一个问题,明明后端接口返回的id是16437976441985843999(只是举例),但是用这个id去查询详情接口时总是报错,后端开发人员查了日志是传的id不对,实际是16437976441985843000,浏览器接口返回的id和后端原本给的id竟然不一致,查了相关文档:

      在Long长度大于17位时,就会出现精度丢失的问题

      简单解释就是:JS自身Number类型的设计原因,原生JS不完全支持long

     根本原因:

      计算机的二进制实现和位数限制有些数无法有限表示。就像一些无理数不能有限表示,如 圆周率 3.1415926…,1.3333… 等。JS 遵循 IEEE 754 规范,采用双精度存储(double precision),占用 64 bit,如图:

      

      其中:1位用来表示符号位;11位用来表示指数;52位表示尾数

      浮点数,比如

      

       此时只能模仿十进制进行四舍五入了,但是二进制只有 0 和 1 两个,于是变为 0 舍 1 入。这即是计算机中部分浮点数运算时出现误差,丢失精度的根本原因。

      大整数的精度丢失和浮点数本质上是一样的,尾数位最大是 52 位,因此 JS 中能精准表示的最大整数是 Math.pow(2, 53),十进制即 9007199254740992。大于 9007199254740992 的可能会丢失精度

      

      看似有穷的数字, 在计算机的二进制表示里却是无穷的,由于存储位数限制因此存在“舍去”,精度丢失就发生了。

      对于前后台传参Long类型而言,JS内置有32位整数,而number类型的安全整数是53位。如果超过53位,则精度会丢失。如果后台传来一个64位的Long型整数,因为超过了53位,所以后台返回的值和前台获取的值会不一样。下面看一下如何处理这种精度丢失问题。

      (以上对于根本原因的解释:原文链接:https://blog.csdn.net/u010028869/java/article/details/86563382)

      

     解决办法:

      1. 最直接的后端人员可把long型值转成String类型给前端,这里主要介绍前端解决方案

      2. 端实现一个json parser

        1> 第一步,安装 -- jison

          npm install jison

        2> 第二步,新增两个文件,并修改其中一个文件关于Number类型转换的逻辑

          在github https://github.com/zaach/jsonlint/tree/master/src 这个链接下载 jsonlint.l 、jinsonlint.y 放在本地文件夹下,在此以公司的vue项目为例,放在static目录下:,如图

          

         

          这两个文件分别是 词表文件 - lexfile - jsonlint.l、语法文件 - grammFile - jsonlint.y

          修改 jsonlint.y 词法文件关于JSONNumber的这段代码:

          源代码这样:

          

          修改后:

           

         3> 第三步,生成我们要的 jsonlint.js

          用第一步jison把第二步的两位文件合成一个我们要的最终插件,在控制台输入:

          

        4> 第四步,引入jsonlint.js文件,以便使用

          

        5> 第五步,在我们自己axios封装的request.js中使用:

          

       最后,我们就可以在接口里看到精确的Long型值了。

       (参考自:https://blog.csdn.net/fifteen718/article/details/82783246?utm_source=blogxgwz9

  • 相关阅读:
    XML错误信息Referenced file contains errors (http://www.springframework.org/schema/beans/spring-beans-4.0.xsd). For more information, right click on the message in the Problems View ...
    Description Resource Path Location Type Cannot change version of project facet Dynamic Web Module to 2.3.
    maven创建web报错Cannot read lifecycle mapping metadata for artifact org.apache.maven.plugins:maven-compiler-plugin:maven-compiler-plugin:3.5.1:runtime Cause: error in opening zip file
    AJAX跨域
    JavaWeb学习总结(转载)
    JDBC学习笔记
    Java动态代理之JDK实现和CGlib实现
    (转)看懂UML类图
    spring boot配置使用fastjson
    python3下django连接mysql数据库
  • 原文地址:https://www.cnblogs.com/fq1017/p/13261720.html
Copyright © 2011-2022 走看看