number.MAX_SAFE_INTEGER 是 9007199254740991(2⁵³−1),表示 javascript 中能安全参与运算且不丢失精度的最大整数;因其采用 IEEE 754 双精度格式,52 位尾数加隐含 1 位共 53 位精度,故 ≥2⁵³ 的整数开始出现精度空缺。

Number.MAX_SAFE_INTEGER 是 JavaScript 中能被精确表示的最大整数,值为 9007199254740991(即 2⁵³ − 1)。它不是“最大可存储数字”,而是“最大能**安全参与运算且不丢失精度**的整数”。
为什么是 2⁵³ − 1?
JavaScript 使用 IEEE 754 双精度浮点格式存储数字,共 64 位:1 位符号、11 位指数、52 位尾数(有效数字位)。虽然尾数只有 52 位,但规格化数会隐含一个前导 1,因此实际可表示 53 位二进制精度。这意味着从 0 开始,所有 ≤ 2⁵³ − 1 的整数都能被唯一、精确表示;而 ≥ 2⁵³ 的整数开始出现“空缺”——两个相邻可表示数之间的间隔大于 1。
- 例如:
9007199254740992 === 9007199254740993返回true(两者都转为同一个双精度值) - 而
9007199254740991 + 1 === 9007199254740992是true,但+2就不再可靠
哪些操作会突破安全整数边界?
并非只有大数才出问题。以下情况容易意外越界:
- 数组长度超过
MAX_SAFE_INTEGER(虽极少发生,但Array(2**53)已不安全) - 时间戳毫秒值在公元 275760 年之后(
date.now()当前远未达到,但长周期计算需留意) - 金融计算中累加大量小单位金额(如微分、纳秒级计时),长期运行后可能溢出
- 使用
parseInt或科学计数法解析超长数字字符串(如parseInt("9007199254740992")得到正确值,但后续运算可能失真)
如何检测和避免精度问题?
不要依赖 typeof x === 'number' 判断是否“安全”。应主动检查:
立即学习“Java免费学习笔记(深入)”;
- 用
Number.isSafeInteger(x)判断单个数值是否在安全范围内 - 对输入做校验:比如 ID、序列号若来自后端且可能超限,先用
String处理,再按需转BigInt - 涉及高精度整数运算(如加密、大数计算),改用
BigInt(注意:BigInt不能与number混用,需显式转换) - 序列生成、分页偏移等逻辑中,避免用
+=累加至超限值;优先用字符串或BigInt维护计数器
常见误区提醒
MAX_SAFE_INTEGER 和 MAX_VALUE 完全不同:MAX_VALUE ≈ 1.8 × 10³⁰⁸,但它只是“最大可表示浮点数”,中间绝大多数值根本无法精确表示整数;
而 MAX_SAFE_INTEGER 虽然小得多,却保证了该范围内每个整数都有唯一、无损的二进制表示。
不复杂但容易忽略。