js中的数字原理
js数字全部是采用的双精度浮点数存储的。想要了解js中的这些最大值,最小值是怎么来的,的就必须知道计算机是如何存储双精度浮点数的。计算机使用IEEE754规范进行存储浮点数,这个规范不仅仅规范了双精度浮点数还规范了单精度浮点数。我们这里讨论双精度浮点数存储方式。
https://baseconvert.com/ieee-754-floating-point
IEEE754 双精度规范
使用8个字节(64位进行存储),结构如下
- 符号位 Sign(S) : 1bit (b63)
- 指数部分Exponent(E) : 11bit (b62-b52)
- 尾数部分Mantissa(M) : 52bit (b51-b0)
表达式 -1^S * 2^E * 1.M
。
1. 符号位说明
为1时表示负数
2. 部分指数理解
指数部分二进制值范围位0 ~ 2047(2^11-1)
,但这个取值范围并不能直接使用,需要减去一个偏移1023(2^10-1)
(除了最高位其他全为1的时)。所以E的取值范围应该为-1022~1023
,为啥不是-1023~1024
呢?因为规定-1023和1024为特殊情况使用。
3. 尾数部分理解
尾数部分对应小数部分,占52bit。0.11为2^-2 + 2^-4
。小数部分最大取值为(1-2^-52
)。
js中的最大值、最小值、精度、正数最小值和安全整数
1. 最大值 Number.MAX_VALUE
指数部分和小数部分都取最大值时代入表达式:2^1023*(1+(1-2^-52))
。
2. 最小值
注意Number.MIN_VALUE时表示的正数最小值,而不是最小值。最小值应为-2^1023*(1+(1-2^-52))
3. 精度Number.EPSILON
两个数的最小差值即尾数部分最后一位是1其他全为0:2^-52
。
4. 正数最小值 Number.MIN_VALUE
开始以为当指数部分最小并且尾数部分最小时则为最小正数:2^-1022*(1+0) 。但是并不是预期值,因为当数据小于了2^-1022是使用非规格化方式表示:指数部分全为0,小数部分向右移动n(第一个1的右边位置)位实际指数标为-1022-n,表达式为-1^S * M^e
。最小正数为2^-1074
例子:
(为规格化)2^-1022
: 0 0000000001 00000000000000000000000000000000000000000000000000000
(非规格化)2^-1023
: 0 0000000000 10000000000000000000000000000000000000000000000000000
5. 安全整数 [Number.MIN_SAFE_INTEGER,Number.MAX_SAFE_INTEGER]
需要安全表示,则需要保证精确,必须保证这个整数必须能使用ieee754规范精确表示,让指数部分与尾部指数刚刚能抵消则能使尾部最后以为变化1数字也变化1。按照此公式2^e* (1+n*2^-52)
看如下三种情况:(n表示尾数按位变化数量)
- 当指数为53时,尾数部分按位变化
1
整个整数会变化2
。此时便不能精确表示整数了 - 当指数为52时,尾数部分按位变化
1
整个整数会变化1
。此时刚刚能最大的精确表示整数 - 当指数为51时,位数部分需要按位变化
2
整个整数会变化1
。此时也能精确表示整数。
当指数部分为52并且尾数部分全是1时为最大能表示的安全整数即2**53-1
那么最大安全整数:2^53-1
最小则为:-(2^53-1)
以上内容是个人的理解,欢迎指正。