11.数字的存储

61 阅读3分钟

数字的存储

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

问题

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

不一定

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

不一定

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

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

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

最大连续整数:9007199254740991

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

16 ~ 17

二进制

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

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

二进制 -> 十进制

1101 -> 123+122+021+120=131*2^3 + 1*2^2 + 0*2^1 + 1*2^0 = 13

11.01 -> 121+120+021+122=3.251*2^1 + 1*2^0 + 0*2^{-1} + 1*2^{-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为底的指数,而不是103段:52位,表示有效数字

举例

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

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

具体的规则是先在尾数前面加上 1. ,然后后面的数字就变成了 1.1111 指数是用1023 - 1027 表示正的指数,也就是整数。而 -1023 到 0 的指数表示小数。

这里还有一个技巧,后面的2的多少次指数,相当于前面的数字小数点往右移动了多少位。

特殊情况

  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...210231.1111111111... * 2 ^ {1023}

能表示的最大的安全整数

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

0 xxxxx 1111111111....

相当于: 25312^{53} - 1

下一位: 2532^{53} 0 xxxxx 0000000000000