每日一报
js的最大有效数字为什么是
JavaScript 中的所有数字都是用 64 位的 IEEE 754 双精度浮点数表示的。
IEEE 754 双精度浮点数
双精度浮点数由三个部分组成:
其中:
- sign(符号位):1 位,用于表示数值的正负。0 表示正数,1 表示负数。
- exponent(指数部分):11 位,用于表示数值的数量级。它决定了浮点数的规模,通过对 11 位的二进制数进行偏移表示(即对指数加上一个偏移量,称为 bias)。
- fraction(尾数部分):52 位,有效位数,也称为尾数,表示数值的精度。
指数部分的具体作用
指数部分是一个 11 位的无符号整数,表示的范围是 0(
样例说明
实际指数值 = 存储的指数值 - 偏移量(1023)
- 如果指数部分存储的是 0(即二进制的 00000000000),则实际指数是 0 - 1023 = -1023,此时通常用于表示特殊值,如次正规数或零。
- 如果指数部分存储的是 1023(即二进制的 01111111111),则实际指数是 1023 - 1023 = 0,表示的是
,即数字的值不需要放大或缩小。 - 如果指数部分存储的是 1024,则实际指数是 1024 - 1023 = 1,表示的是
,即数字的值需要乘以 2。 - 如果指数部分存储的是 1022,则实际指数是 1022 - 1023 = -1,表示的是
,即数字的值要缩小两倍。 - 如果指数部分存储的是 0(即二进制的 11111111111),则实际指数是 2047 - 1023 = 1024,此时通常通常用于表示特殊值,如
无穷大
或NaN
。
由于 11 位可以表示的二进制数范围是 0 到 2047,而通过偏移量 1023,除去特殊位(当存储指数位为 −1022 (最小,即 1-1023) 到 1023 (最大,即 2046 - 2023)
。
可以看出双精度浮点数在 JavaScript 中可以表示非常大的数值范围,但是在超过安全整数范围时,可能会出现精度丢失的原因。
那么问题来了,最大的安全整数为什么为 Math.pow(2,53) - 1
呢?
由公式
可以得知 fraction(尾数部分)
最大为 52
位数,再加上前面 1
(由于 IEEE 754 标准在尾数部分隐含了一个“1”(规范化数的前导 1),因此尾数实际上具有 53 位的精度。),1023
)。那么有效位数决定了浮点数可以精确表示的整数的范围。对于 53 位有效位数来说:
最大可以表示的精确整数范围是从