JavaScript的Number类型统一采用IEEE 754双精度浮点格式(64位,1-11-52结构)存储所有数值;符号位1位、指数位11位(偏移量1023)、尾数位52位(隐含前导1,共53位精度);可精确表示绝对值≤2⁵³−1的整数,小数因二进制无限循环被截断导致精度误差,如0.1+0.2≠0.3。

JavaScript 的 Number 类型不以二进制字符串形式存储,而是统一采用 IEEE 754 双精度浮点格式(64 位) 存储所有数值——整数、小数、正负数、无穷大、NaN 都是同一套二进制布局。
这个 64 位结构严格划分为三部分:
- 1 位符号位(Sign):0 表示正数,1 表示负数
- 11 位指数位(Exponent):采用偏移量(Bias = 1023),真实指数 = 存储值 − 1023,范围为 −1022 到 +1023
- 52 位尾数位(Fraction / Mantissa):隐含前导 1(即实际有效精度为 53 位),存储小数点后的二进制位
例如数字 144:
→ 二进制为 10010000
→ 科学计数法表示为 1.001 × 2⁷(注意:10010000 = 1.0010000 × 2⁷)
→ 符号位 0,指数存储值 1023 + 7 = 1030(二进制 10000000110),尾数填 001 后补零至 52 位
→ 最终拼成 64 位比特串
再比如 0.1:
→ 十进制 0.1 在二进制中是无限循环小数 0.0001100110011…
→ 截断并舍入到 52 位尾数后,已存在微小误差
→ 这就是 0.1 + 0.2 !== 0.3 的根本原因
注:你写的 0b1010 或 0xFF 只是源码中的字面量语法糖,运行时立刻转为上述 64 位浮点表示,不再保留“二进制”或“十六进制”的身份。
如何查看某个 Number 的真实 64 位二进制布局?
不能用 .toString(2)(它只转数值的十进制等价物,再转二进制字符串,丢失 IEEE 754 结构):
立即学习“Java免费学习笔记(深入)”;
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
function toBinary64(num) {
const buffer = new Float64Array([num]).buffer;
const bytes = new Uint8Array(buffer);
return Array.from(bytes)
.map(b => b.toString(2).padStart(8, '0'))
.reverse() // IEEE 754 小端序?注意:Float64Array 默认平台字节序,通常为小端;若需标准大端 IEEE 布局,应按规范顺序拼接
.join('');
}
// toBinary64(3.14) → 得到完整的 64 位 IEEE 754 表示(含符号、指数、尾数)为什么位运算看起来像在操作“二进制”?
因为 &、|、<< 等操作符会临时把 Number 转为 32 位有符号整数(补码),再逐位计算,结果再转回 Number。这不是读取原始 64 位浮点布局,而是另起一套整数位逻辑。
-
3.7 | 0→3(小数被截断) -
-1 >> 0→-1(算术右移,保持符号) -
-1 >>> 0→4294967295(无符号右移,等价于 32 位补码解释为正整数)
大整数和精度边界
由于只有 53 位有效精度,JavaScript 能安全精确表示的整数范围是:
-
Number.MIN_SAFE_INTEGER === -9007199254740991 -
Number.MAX_SAFE_INTEGER === 9007199254740991
超出该范围(如 9007199254740992 + 1)可能无法区分相邻整数,此时应改用 BigInt。
不复杂但容易忽略

















