极客时间返利平台,你可以在上边通过山月的链接购买课程,并添加我的微信 (shanyue94) 领取返现。

# 什么是安全整数,如何判断一个整数是安全整数

Issue

欢迎在 Gtihub Issue 中回答此问题: Issue 648 (opens new window)

根据 MDN 的文档描述:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Number/isSafeInteger (opens new window)

一个安全整数是一个符合下面条件的整数:

  1. 可以准确地表示为一个 IEEE-754 双精度数字,
  2. 其 IEEE-754 表示不能是舍入任何其他整数以适应 IEEE-754 表示的结果。.

Number.MAX_SAFE_INTEGER 是最大安全整数,Number.isSafeInteger() 用来判断一个数值是否为安全整数。

而在安全整数之外,加减计算则会发生精度问题,如下:

Number.MAX_SAFE_INTEGER;
//=> 9007199254740991

Number.MAX_SAFE_INTEGER + 1;
//=> 9007199254740992

// 计算错误,结果应该是 9007199254740993
Number.MAX_SAFE_INTEGER + 2;
//=> 9007199254740992

而安全整数的问题,与 0.1+0.2 的问题类似。在 Javascript 中,整数被存储为双精度浮点数,而在整数大到一定程度后,就会导致精读失真。

如下,最大安全整数可以精准表示。以下截图使用 https://devtool.tech/double-type (opens new window) 进行实时转换整数的 IEEE754 表示。

在双精度浮点数中,尾数位有 52 位,而最大安全整数为 2 ** 53 - 1,通过以下截图,也可以看做是 1.9999999999999998 * 2 ** (1075-1023)

但是最大安全整数加 2,尾数位会溢出,导致该数值无法精准表示。

Author

回答者: Feahter (opens new window)

自 2003 年以后,电脑普遍采用 x86-64 架构,而架构的数据单元的固定为 64 位(8 字节) 64 位双精度浮点数(double-precision 64-bit floating point format) 其中双精度浮点数是用来表示带有小数部分的实数 双精度浮点数最多有 15 或 16 位十进制有效数字,即 53 位二进制有效数字 IEEE-754 规定 64 位二进制存储单元由 3 部分组成 1+11+52 1 是表示正负数 11 是表示指数位置 52 则是数据值位置 所以因为单位存储空间限制,安全整数的范围是 1 位正数加 52 位数据位 即 53 位二进制,超过只能溢出到指数位置存储,无法安全表示,所以安全整数的位数是 Number.MAX_SAFE_INTEGER.toString(2).length;

https://github.com/anjia/blog/issues/87

Last Updated: 11/5/2022, 8:38:06 PM