js中所有数字均为ieee 754双精度浮点数,由1位符号、11位指数、52位尾数(+隐含1位)构成,导致0.1+0.2≠0.3;安全整数范围为±9007199254740991,超限需用bigint;金融计算应避免小数运算,改用整数单位或decimal.js。

JS 中所有数字都统一为 IEEE 754 双精度浮点数(64 位),没有整型、浮点型之分。这不是设计缺陷,而是标准选择——它决定了你能安全算什么、为什么 0.1 + 0.2 ≠ 0.3、以及何时该换 BigInt。
数值怎么存:1 位符号 + 11 位指数 + 52 位尾数
一个 number 实际由三部分组成:
- 符号位(1 bit):0 表示正,1 表示负
- 指数位(11 bit):决定小数点位置,可表示范围约 ±10³⁰⁸
- 尾数(52 bit)+ 隐含的 1 位(彩蛋位)= 53 位有效精度:真正能“无损”表示的二进制位数
关键点:十进制小数(如 0.1)在二进制中是无限循环小数(0.0001100110011…),只能截断存储 → 从源头就带误差。加法只是把两个近似值再叠加一次,结果自然不是精确的 0.3。
安全整数边界:±9007199254740991
因为只有 53 位有效精度,JS 能精确表示的整数上限是 Number.MAX_SAFE_INTEGER(2⁵³ − 1 = 9007199254740991)。超出后:
- 相邻可表示整数的间隔变大(比如 2⁵³ 和 2⁵³+2 可表示,但 2⁵³+1 不行)
-
9007199254740992 === 9007199254740993返回 true - 用
Number.isSafeInteger(n)可检测是否落在安全范围内
常见陷阱与应对策略
不是所有问题都要“修复”,关键是选对工具:
- 金融/计费场景:别用 number 做小数运算。改用整数单位(如“分”代替“元”),或引入 decimal.js / big.js 库
-
比较小数:避免
===直接比,用Math.abs(a - b) -
超大整数(>2⁵³):用
BigInt(末尾加n),但注意它不能和 number 混合运算,且不支持小数 -
解析字符串数字:
parseInt("010")在旧环境可能当八进制,建议显式传参parseInt("010", 10);更稳妥用Number("010")或一元加号+"010"
特殊值不是异常,而是设计的一部分
Infinity、-Infinity、NaN 都是合法 number 值:
-
1 / 0→Infinity,-1 / 0→-Infinity,它们参与运算有明确定义(如Infinity + 1 === Infinity) -
NaN表示“不可表示的数值结果”,它不等于任何值(包括自己),检测必须用Number.isNaN()或isNaN()(注意后者会强制转换) -
0和-0在 JS 中是两个不同值(Object.is(0, -0)返回 false),除法中表现不同:1 / 0 === Infinity,1 / -0 === -Infinity











