数字的存储
在对精度要求很高的系统中,或要对小数的运算结果进行比较时,需要特别谨慎
问题
- JS中的小数运算是精确的吗?
不一定
- JS中的整数运算是精确的吗?
不一定
- JS中表示的整数是连续的吗?
不是,当JS的数字很大的时候,不再连续。
- JS中表示的最大数字是多少?
最大连续整数:9007199254740991
- JS中能表示的数字的有效位数是多少?
16 ~ 17
二进制
现实世界中:十进制,10个数字,逢十进一
计算机世界中:二进制,2个数字,逢二进一
二进制 -> 十进制
1101 ->
11.01 ->
十进制 -> 二进制
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. ,然后后面的数字就变成了 1.1111 指数是用1023 - 1027 表示正的指数,也就是整数。而 -1023 到 0 的指数表示小数。
这里还有一个技巧,后面的2的多少次指数,相当于前面的数字小数点往右移动了多少位。
特殊情况
- 指数为0,尾数为0,表示数字 0
- 符号为0,指数为2047,尾数为0,表示正无穷
Infinity: 0 11111111111 00000000000...
- 符号为1,指数为2047,尾数为0,表示负无穷
-Infinity: 1 11111111111 00000000000...
- 指数为2047,尾数不为0,表示NaN
NaN: 1 11111111111 01001010000...
一个正常的数字,指数部分最多是2046
能表示的最大数字
0 11111111110 1111111111.........
相当于:
能表示的最大的安全整数
安全数字:从1开始到该数字,均是连续的整数,并且该数字的下一个整数是存在的。
0 xxxxx 1111111111....
相当于:
下一位: 0 xxxxx 0000000000000