Skip to content

数字的存储

在对精度要求很高的系统中,或要对小数的运算结果进行比较时,需要特别谨慎

问题

  1. JS中的小数运算是精确的吗?

不一定

  1. JS中的整数运算是精确的吗?

不一定

  1. JS中表示的整数是连续的吗?

不是,当JS的数字很大的时候,不再连续。

  1. JS中表示的最大数字是多少?

最大连续整数:9007199254740991

  1. JS中能表示的数字的有效位数是多少?

16 ~ 17

二进制

现实世界中:十进制,10个数字,逢十进一

计算机世界中:二进制,2个数字,逢二进一

二进制 -> 十进制

1101 -> $12^3 + 12^2 + 02^1 + 12^0 = 13$

11.01 -> $12^1 + 12^0 + 02^{-1} + 12^{-2} = 3.25$

十进制 -> 二进制

13 -> 1101

13 / 2  商 6    余  1
6  / 2  商 3    余  0
3  / 2  商 1    余  1
1  / 2  商 0    余  1
余数从下往上看

3.25 -> 11.01

整数部分一样

小数部分

0.25 * 2    0.5     整数部分:0
0.5  * 2    1.0     整数部分:1
整数部分从上往下看

为什么JS的小数运算不精确

十进制的小数,转换为二进制后,可能是无限小数,但是计算机对数字的存储能力有限,因此会丢失一些数据。

十进制数 0.3 -> 0.010011001100110011001.....

0.3*2   0.6     0
0.6*2   1.2     1
0.2*2   0.4     0
0.4*2   0.8     0
0.8*2   1.6     1
0.6*2   1.2     1
0.2*2   0.4     0
......
整数部分从上往下看

JS如何存储数字

整数法、浮点法

JS中,存储的所有数字,都按照浮点法存放。

浮点法存放的数字,叫做浮点数(float),浮点数分为单精度和双精度。

JS中,使用双精度存放浮点数,IEEE 754。

存放方式

JS在计算机中,给每个数字开辟一块内存空间,尺寸固定为64位

在计算机中,位(bit)是最小的存储单位,简称为bit 1 byte = 8 bit 1 KB = 1024 byte 1 MB = 1024 KB 1 GB = 1024 MB

[第1段][第2段][第3段]

第1段:1位,表示符号位,如果为1,是负数,如果为0,是正数
第2段:11位,表示指数位,这里的指数是2为底的指数,而不是10
第3段:52位,表示有效数字

举例

0     1000 0000 011    1111 0000 0000 0000....

相当于: $1.1111 * 2 ^ {1027 - 1023} $

特殊情况

  1. 指数为0,尾数为0,表示数字 0
  2. 符号为0,指数为2047,尾数为0,表示正无穷
Infinity: 0 11111111111 00000000000...
  1. 符号为1,指数为2047,尾数为0,表示负无穷
-Infinity: 1 11111111111 00000000000...
  1. 指数为2047,尾数不为0,表示NaN
NaN: 1 11111111111 01001010000...

一个正常的数字,指数部分最多是2046

能表示的最大数字

0 11111111110 1111111111.........

相当于: $1.1111111111... * 2 ^ 1023 $

能表示的最大的安全整数

安全数字:从1开始到该数字,均是连续的整数,并且该数字的下一个整数是存在的。

0 xxxxx 1111111111....

相当于: $2^53 - 1$

下一位: $2^53$ 0 xxxxx 0000000000000

MIT License