1、为什么JavaScript的整数最大范围不是±2^63^,而是±2^53^

这是一个关于 IEEE 754 浮点数标准的经典问题。

根本原因:JS 用浮点数表示整数

JavaScript 没有独立的整数类型,所有数字(包括整数)都用 64位双精度浮点数(IEEE 754 double) 存储。

64位浮点数的内存布局如下:## 核心原因:53位有效精度

IEEE 754 双精度浮点数用 52位尾数 存储小数部分,但规格化表示时,整数部分固定为 1(比如 1.101011...),这个 1 不需要显式存储,因此实际有效精度是 52 + 1 = 53 位


为什么超过 2⁵³ 就不安全?

当整数超过 2⁵³ 时,相邻两个浮点数之间的间距变为 2,也就是说有些整数已经无法被精确表示:

2**53          // 9007199254740992  ✅ 精确
2**53 + 1      // 9007199254740992  ❌ 和上面相等!被"舍入"了
2**53 + 2      // 9007199254740994  ✅ 又精确了(偶数)

这是浮点数精度间距(ULP, Unit in the Last Place)的问题——指数每增大一档,尾数能表示的粒度就粗一倍。


那 ±2⁶³ 是哪来的?

那是 64位整数类型(如 C/Java 的 long,或 JS 的 BigInt)的范围,它用全部 64 位存整数,没有指数/尾数的分配,所以能精确表示 ±2⁶³ 内的每一个整数。

JS 要用同等范围,需要:

BigInt(2) ** 63n  // 精确,使用 BigInt

简单记忆:64位浮点 ≠ 64位整数,浮点把空间花在了指数上,真正留给整数精度的只有 53 位。

library(Seurat)