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 结构
每个 `Number` 在内存中严格占用 64 位,划分为三段: - 1 位符号位:0 表示正,1 表示负 - 11 位指数位:采用偏移量(Bias = 1023),真实指数 = 存储值 − 1023,范围是 −1022 到 +1023 - 52 位尾数位:隐含一个前导 1,实际有效精度为 53 位二进制(即 1.xxxx 形式)比如整数 1:二进制科学计数法为 1.0 × 2⁰,符号位为 0,指数存储值为 1023(二进制 01111111111),尾数全 0,拼起来就是完整的 64 位比特串。
能精确表示哪些整数?
由于只有 53 位有效精度,JavaScript 能**唯一、无歧义表示所有绝对值 ≤ 2⁵³ − 1 的整数**: - `Number.MAX_SAFE_INTEGER === 9007199254740991` - `Number.MIN_SAFE_INTEGER === -9007199254740991`超出这个范围后,多个整数会映射到同一个双精度值。例如:
-
9007199254740992 === 9007199254740993返回true -
Math.pow(2, 53) + 1 === Math.pow(2, 53)也返回true
这并非 bug,而是 IEEE 754 的自然限制。
立即学习“Java免费学习笔记(深入)”;
小数为什么算不准?
十进制小数如 `0.1` 和 `0.2` 在二进制中是无限循环小数: - `0.1` → `0.0001100110011…₂`(循环) - 存储时只能截断或舍入到 52 位尾数,造成微小误差 - 运算时误差累积,导致 `0.1 + 0.2 !== 0.3`比较小数应避免直接用 ===,推荐:
- 使用容差判断:
Math.abs(a - b) < Number.EPSILON - 金额等关键场景转为整数运算:
(0.1 * 100 + 0.2 * 100) / 100 === 0.3
特殊值怎么编码?
IEEE 754 预留特定比特模式表示非普通数值: - ±0:指数全 0 + 尾数全 0;符号位决定正负(`1 / -0 === -Infinity`) - ±Infinity:指数全 1 + 尾数全 0 - NaN:指数全 1 + 尾数非全 0;所有 NaN 均不等于自身(`NaN === NaN` 为 `false`)这些不是 JS “发明”的常量,而是底层比特模式的语义封装,Number.NaN、Infinity 等只是可读性包装。
不复杂但容易忽略


















