从js的双精度浮点数说起


背景

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

看下图:

v2-4b5ed4311e5bfa420beee3adda2993a7_720w.png
将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

微信图片_20230308141753.jpg
当超出该数字时会发生溢出,在浏览器输入9007199254740993时显示9007199254740992,输入9007199254740995时显示9007199254740996

image.png

image.png
课件已经发生溢出,下面来看看是怎么溢出的。
9007199254740991用二进制表示为

1.111(521)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 是否相等

image.png

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

文章作者: Icon
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Icon !
评论
  目录