背景
javascript 中使用 IEEE754 标准来规定浮点数。
在 IEEE754 中,规定了4种方法用来表示浮点数:
- 单精度(32位)
- 延伸单精度(43比特以上)
- 双精度(64位)
- 延伸双精度(79比特以上)
js中使用的就是其中的双精度。
IEEE754 双精度
这里用 10.25 来演示,首先将 10.25 用二进制表示:
10 -> 1010
0.25 -> 01
10.25 -> 1010.01
使用科学计数法表示:1.01001x10^3
看下图:
将64位分为了三部分
- sign -> 用来记录正负(0表示正,1表示负)。
- exponent -> 记录指数,共11位(2^11个)。
由于指数可为负数,所以分为两部分,000 0000 0001 - 011 1111 1111表示负指数,100 0000 0001 - 111 1111 1110表示正指数。所以指数3就是011 1111 1111右移3位,表示为100 0000 0010
- mantissa -> 尾数,表示二进制科学计数法的小数位
01001 表示为0100 1000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
注意:这里省略的二进制科学计数法的整数1,由于必定为1,所以计算机省略了,但是计算的时候要算上
所以 1.01001x10^3 表示为:
0 100 0000 0010 0100 1000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
MAX_SAFE_INTEGER
MAX_SAFE_INTEGER 是 Number 的一个常量,代表的是 javascript 中最大的安全整数
那么 MAX_SAFE_INTEGER 是怎么得到的呢?
为了得到这个数,我们使尾数位全为1,即:1111 …. 1111(52位),再加上整数位1,共53个1。
53个1 = 1000…(53个0) - 1 = 2^53 - 1 = 9007199254740991
当超出该数字时会发生溢出,在浏览器输入9007199254740993时显示9007199254740992,输入9007199254740995时显示9007199254740996
课件已经发生溢出,下面来看看是怎么溢出的。
9007199254740991用二进制表示为
1.111(52个1)x2^52
0 100 0011 0011 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111
9007199254740992用二进制表示为
2^53
0 100 0011 0100 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0
可以看出多出一位,按照向偶舍入的规则,不会产生进位。
所以表示为:
0 100 0011 0100 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
9007199254740993用二进制表示为
可以看出两次的结果一样。
可以在浏览器上测试 9007199254740992 与 9007199254740993 是否相等
BigInt
javascript 为了能够计算安全整数外的大数,引入了 BigInt 基本数据类型,可以用来表示和计算任何数字。
// 定义
const bigInt1 = BigInt(1);
const bigInt2 = 3n; // 后面加 n 即为BigInt类型
// 计算
console.log(BigInt(1) + BigInt(2)); // 3n
console.log(BigInt(1) + 3n); // 4n