javascript的number类型统一采用ieee 754双精度浮点格式(64位,1-11-52结构)存储,无整数与浮点数之分;可精确表示绝对值≤2⁵³−1的整数,小数因二进制无限循环被截断导致0.1+0.2≠0.3;±0、±infinity、nan均由标准定义的比特模式表示。

JavaScript 的 Number 类型没有整数和浮点数之分,所有数字都按 IEEE 754 双精度浮点格式(64 位)存储和运算。理解这个底层标准,是写出健壮数值逻辑的关键。
64 位怎么拆:1-11-52 结构
每个 JavaScript 数字在内存中占 64 位,严格划分为三段:
- 1 位符号位:0 表示正,1 表示负
- 11 位指数位:存储值 = 真实指数 + 1023(偏移量),所以真实指数范围是 −1022 到 +1023
- 52 位尾数位:实际有效数字共 53 位,因为规格化数隐含一个前导 1(即 1.xxxx 形式)
例如,整数 1 的二进制是 1.0,规格化后尾数存全 0,指数为 0 → 存储指数 = 1023 → 二进制为 01111111111;符号位为 0,尾数 52 位全 0,就组成了完整的 64 位表示。
能精确表示哪些整数?
由于只有 53 位有效精度,JavaScript 能唯一、无歧义地表示所有绝对值 ≤ 2⁵³ − 1 的整数,即:
Number.MAX_SAFE_INTEGER === 9007199254740991Number.MIN_SAFE_INTEGER === -9007199254740991
超过这个范围,连续整数开始“合并”——比如 9007199254740992 === 9007199254740993 返回 true。这不是 bug,而是双精度浮点数的自然限制。用 Number.isSafeInteger(n) 可以安全检测。
小数为什么算不准?
很多十进制小数在二进制中是无限循环小数,例如:
-
0.1→0.00011001100110011…(无限循环) -
0.2→0.0011001100110011…(无限循环)
它们只能被截断或舍入到 53 位精度,导致存储值本身就是近似值。因此 0.1 + 0.2 !== 0.3。比较时应改用误差容忍方式:Math.abs(a - b) 或自定义阈值(如 <code>1e-10)。
特殊值不是魔法,是标准定义
NaN、Infinity、-0 都有明确的 IEEE 754 比特模式:
-
±0:指数全 0 + 尾数全 0;符号位决定正负;
1 / -0得-Infinity -
±Infinity:指数全 1 + 尾数全 0;如
1 / 0或超限计算结果 -
NaN:指数全 1 + 尾数非全 0;所有 NaN 均不等于自身(
NaN === NaN为false)
这些行为不是 JavaScript 自创,而是标准强制要求。检测 NaN 必须用 isNaN() 或 Number.isNaN(),不能用相等比较。











