生而自由

自由而无用的灵魂

JavaScript大整数精度丢失问题

遇到一个case,后端通过ajax向前端返回JSON数据时,其中有一个较大的整数199941234302361658,页面却展示为199941234302361660。

研究了一下,JavaScript 只有一种数字类型:Number,Number是双精度浮点数,与许多其他编程语言不同,JavaScript 不定义不同类型的数字,比如整数、短、长、浮点等等。因此在JavaScript中,数字不分为整数类型和浮点类型,所有的数字都是浮点类型。

在表达整数时,Number能表示的整数范围是[-2^53, 2^53]。因为Number有8个字节64位,其中包括1位符号位,11位指数位,52位尾数位。

可以用Number.MAX_SAFE_INTEGER和Number.MIN_SAFE_INTEGER查看最大安全整数、最小安全整数。

const max = Number.MAX_SAFE_INTEGER;
9007199254740991

注意最大安全整数是2^53-1,所以它还能正确地加一次1:

max + 1
9007199254740992

再加一次,就出问题了:

max + 2
9007199254740992

可以发现Number.MAX_SAFE_INTEGER是一个长度为16位的整数,因此需要牢记数字长度达到16位及以上时就需要警惕了。

在这个case中,JSON反序列化时把数字转化为了Number类型,所以导致了精度溢出的问题,在返回JSON时把这个字段改为字符串型即可。

点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据