Skip to content

每日一报

js的最大有效数字为什么是 2531

JavaScript 中的所有数字都是用 64 位的 IEEE 754 双精度浮点数表示的。

IEEE 754 双精度浮点数

双精度浮点数由三个部分组成:

(1)sign×(1.fraction)×2exponent1023

其中:

  • sign(符号位):1 位,用于表示数值的正负。0 表示正数,1 表示负数。
  • exponent(指数部分):11 位,用于表示数值的数量级。它决定了浮点数的规模,通过对 11 位的二进制数进行偏移表示(即对指数加上一个偏移量,称为 bias)。
  • fraction(尾数部分):52 位,有效位数,也称为尾数,表示数值的精度。

指数部分的具体作用

指数部分是一个 11 位的无符号整数,表示的范围是 0(20) 到 2047(2111)。但指数实际上表示的是浮点数的二进制指数部分。因此,为了表示正负指数,采用偏移量(bias)的方式来表示。对于双精度浮点数,bias 是 1023。

样例说明

实际指数值 = 存储的指数值 - 偏移量(1023)

  • 如果指数部分存储的是 0(即二进制的 00000000000),则实际指数是 0 - 1023 = -1023,此时通常用于表示特殊值,如次正规数或零。
  • 如果指数部分存储的是 1023(即二进制的 01111111111),则实际指数是 1023 - 1023 = 0,表示的是 20,即数字的值不需要放大或缩小。
  • 如果指数部分存储的是 1024,则实际指数是 1024 - 1023 = 1,表示的是 21,即数字的值需要乘以 2。
  • 如果指数部分存储的是 1022,则实际指数是 1022 - 1023 = -1,表示的是 21,即数字的值要缩小两倍。
  • 如果指数部分存储的是 0(即二进制的 11111111111),则实际指数是 2047 - 1023 = 1024,此时通常通常用于表示特殊值,如无穷大NaN

由于 11 位可以表示的二进制数范围是 0 到 2047,而通过偏移量 1023,除去特殊位(当存储指数位为 0 和 2047(即 2111))时,我们可以表示的实际指数范围是: −1022 (最小,即 1-1023) 到 1023 (最大,即 2046 - 2023)

可以看出双精度浮点数在 JavaScript 中可以表示非常大的数值范围,但是在超过安全整数范围时,可能会出现精度丢失的原因。

那么问题来了,最大的安全整数为什么为 Math.pow(2,53) - 1 呢?

由公式

(1)sign×(1.fraction)×2exponent1023

可以得知 fraction(尾数部分) 最大为 52 位数,再加上前面 1(由于 IEEE 754 标准在尾数部分隐含了一个“1”(规范化数的前导 1),因此尾数实际上具有 53 位的精度。),2exponent1023 本质上可以看作右移的偏移量(由上可知最大可右移 1023 )。那么有效位数决定了浮点数可以精确表示的整数的范围。对于 53 位有效位数来说:

最大可以表示的精确整数范围是从 253+12531

Contributors

Changelog

Discuss

Released under the CC BY-SA 4.0 License. (2619af4)