JavaScript加法对超安全整数(>2^53−1)不报错但会丢失精度,因双精度浮点数仅53位有效位;应使用Number.isSafeInteger()检测,大整数运算需用BigInt。

JavaScript 中的算术运算符(如 +)对超出 Number.MAX_SAFE_INTEGER(即 253 − 1 = 9007199254740991)的整数加法,**不会报错,但会失去精度**——因为 JavaScript 使用 IEEE 754 双精度浮点数表示所有数字,超出安全整数范围后,无法唯一、准确地表示每个整数。
为什么加法结果会“不准”?
双精度浮点数只有 53 位有效位(significand),能精确表示的整数上限就是 253 − 1。超过这个值后,相邻可表示数之间的间隔大于 1(例如,在 253 附近,最小可分辨差值是 2)。因此:
-
9007199254740991 + 1→9007199254740992(仍精确) -
9007199254740992 + 1→9007199254740992(丢失+1,结果不变) -
9007199254740993 + 1→9007199254740994(看似正常,但该值本身可能已不是你写的那个“精确整数”)
如何检测是否发生精度丢失?
不能只看结果是否为 NaN 或 Infinity——它们没出现,不代表结果可靠。正确做法是:
- 用
Number.isSafeInteger()检查参与运算的原始操作数是否都在安全范围内 - 加法后也检查结果:
Number.isSafeInteger(a) && Number.isSafeInteger(b) && Number.isSafeInteger(a + b) - 注意:即使
a和b是安全整数,a + b仍可能溢出安全范围(如MAX_SAFE_INTEGER + 1)
需要精确大整数加法?用 BigInt
ES2020 起支持 BigInt,后缀 n 或 BigInt() 构造,可安全进行任意精度整数运算:
立即学习“Java免费学习笔记(深入)”;
-
9007199254740992n + 1n === 9007199254740993n(✅ 精确) - ⚠️ 注意:
BigInt不能与number混用:9007199254740992n + 1会抛TypeError - 需统一类型:
BigInt(9007199254740992) + BigInt(1)或写成9007199254740992n + 1n
实际开发建议
大多数场景(如计数、ID、时间戳)应优先使用安全整数;若明确需超大整数计算(如密码学、高精度金融中间计算),则:
- 全程使用
BigInt,避免隐式转换 - 与 JSON 交互时注意:
JSON.stringify(123n)抛错,需手动转为字符串或 number(仅当不超安全范围) - 库函数如
Math.pow、parseInt返回number,结果可能不精确,必要时用BigInt替代逻辑


















