解决 javascript 处理 Long 长度大于 17 位度丢失精度的问题

解决问题的第一途径,最好从接口文档里面寻找方法。

JavaScript 数据类型和数据结构

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Data_structures

直接引用原文:


数据类型

最新的 ECMAScript 标准定义了 8 种数据类型:

Number 数字类型

根据 ECMAScript 标准,JavaScript 中只有一种数字类型:基于 IEEE 754 标准的双精度 64 位二进制格式的值(-(2^53 -1) 到 (2^53 -1)。它并没有为整数给出一种特定的类型。除了能够表示浮点数外,还有一些带符号的值:+Infinity-InfinityNaN (非数值,Not-a-Number)。

要检查值是否大于或小于 +/-Infinity,你可以使用常量 Number.MAX_VALUENumber.MIN_VALUE。另外在 ECMAScript 6 中,你也可以通过 Number.isSafeInteger() 方法还有 Number.MAX_SAFE_INTEGERNumber.MIN_SAFE_INTEGER 来检查值是否在双精度浮点数的取值范围内。 超出这个范围,JavaScript 中的数字不再安全了,也就是只有 second mathematical interger 可以在 JavaScript 数字类型中正确表现。

数字类型中只有一个整数有两种表示方法: 0 可表示为 -0 和 +0("0" 是 +0 的简写)。 在实践中,这也几乎没有影响。 例如 +0 === -0 为真。 但是,你可能要注意除以 0 的时候:

42 / +0; // Infinity
42 / -0; // -Infinity

尽管一个数字常常仅代表它本身的值,但 JavaScript 提供了一些位运算符。 这些位运算符和一个单一数字通过位操作可以用来表现一些布尔值。然而自从 JavaScript 提供其他的方式来表示一组布尔值(如一个布尔值数组或一个布尔值分配给命名属性的对象)后,这种方式通常被认为是不好的。位操作也容易使代码难以阅读,理解和维护, 在一些非常受限的情况下,可能需要用到这些技术,比如试图应付本地存储的存储限制。 位操作只应该是用来优化尺寸的最后选择。

JavaScript 最大的安全数为 17 位, Math.pow(2, 53) - 1,即 9007199254740991。

根据双精度浮点数的构成,精度位数是 53 bit。安全数的意思是在 -2^53 ~ 2^53 内的整数(不包括边界)与唯一的双精度浮点数互相对应。举个例子比较好理解:Math.pow(2, 53) === Math.pow(2, 53) + 1 // trueMath.pow(2, 53) 竟然与 Math.pow(2, 53) + 1 相等!这是因为 Math.pow(2, 53) + 1 已经超过了尾数的精度限制(53 bit),在这个例子中 Math.pow(2, 53) 和 Math.pow(2, 53) + 1 对应了同一个双精度浮点数。所以 Math.pow(2, 53) 就不是安全数了。最大的安全数为 Math.pow(2, 53) - 1,即 9007199254740991。

作者:牧云云
链接:https://www.zhihu.com/question/29010688/answer/503100778
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

JavaScript 处理 Long 长度大于 17 位度丢失的问题

对于 Long 类型的数据,如果我们在 Controller 层将结果序列化为 JSON,直接传给前端的话,在 Long 长度大于 17 位时会出现精度丢失的问题。如何避免精度丢失呢?最常用的办法就是将 Long 类型字段统一转成 String 类型。

参考:
1.彻底解决 JS 处理 Long 类型精度丢失问题(一)
2.彻底解决 JS 处理 Long 类型精度丢失问题(二)

  • JavaScript

    JavaScript 一种动态类型、弱类型、基于原型的直译式脚本语言,内置支持类型。它的解释器被称为 JavaScript 引擎,为浏览器的一部分,广泛用于客户端的脚本语言,最早是在 HTML 网页上使用,用来给 HTML 网页增加动态功能。

    530 引用 • 1038 回帖 • 782 关注
1 操作
cloudlang 在 2020-01-08 18:20:44 更新了该帖
2 回帖
请输入回帖内容...
  • wanming001

    后端转 String 到前端就完事了,或者注解的方式

    @JsonSerialize(using = ToStringSerializer.class)
    

    1 回复
  • 其他回帖
  • cloudlang

    这个针对局部改动比较方便,为了保持框架接口输出一致性,我采用了全局配置和自定义过滤器