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)