BigInt

参考:https://blog.csdn.net/m0_50914413/article/details/112706493

1. 为什么会出现 BigInt

BigInt 数据类型的目的是比 Number 数据类型支持的范围更大的整数值以任意精度表示整数的能力尤为重要。使用 BigInt整数溢出将不再是问题

因为在 js 中的数字类型是按照 IEEE 754-2008 标准的定义,所有数字都以 双精度64位浮点 格式表示。因为在 IEEE 754 标准下浮点数的舍入模式是一下4类:

最近舍入 即向距离最近的浮点数舍入,若存在两个同样接近的数,则选择偶数作为舍入值
向零舍入 又称截断舍入,将多余的精度位截掉,即取舍入后绝对值较小的值
正向舍入 也称正无穷舍入,即舍入后结果大于原值
负向舍入 也称负无穷舍入,即舍入后结果小于原值

所以在此标准下,无法精确表示的非常大的整数将自动四舍五入。确切地说,JS 中的 Number 类型只能安全地表示 -9007199254740991 (-(2^53-1))9007199254740991(2^53-1) 之间的整数,任何超出此范围的整数值都可能失去精度。

console.log(9999999999999999); //10000000000000000

因为该整数大于 JS Number 类型所能表示的最大整数,所以它被四舍五入了,意外的四舍五入会损害程序的可靠性和安全性。例如:

// 注意最后一位的数字
console.log(9007199254740992 === 9007199254740993); //true

原因是因为,JS 提供 Number.MAX_SAFE_INTEGER 常量表示最大安全整数,Number.MIN_SAFE_INTEGER常量表示最小安全整数。

可以把它打印出来:

const minInt = Number.MIN_SAFE_INTEGER;

console.log(minInt); //-9007199254740991

console.log(minInt - 5); //-9007199254740996

// 注意它是如何输出与上面相同的值的
console.log(minInt - 4); // -9007199254740996

2. BigInt

使用 bignumber.js 处理大整数

使用 BigInt 应用程序不再需要变通方法或库来安全地表示Number.MAX_SAFE_INTEGERNumber.Min_SAFE_INTEGER之外的整数。 现在可以在标准 JS 中执行对大整数的算术运算,而不会有精度损失的风险。

要创建BigInt,只需在整数的末尾追加 n 即可。比如:

console.log(9007199254740995n); //9007199254740995n
console.log(9007199254740995); //9007199254740996

或者可以调用 BigInt() 构造函数

BigInt("9007199254740995"); //9007199254740995n

2.1 BigInt 构造函数

与其他基本类型一样,可以使用构造函数创建BigInt。传递给BigInt()的参数将自动转换为BigInt

BigInt("10");    //10n
BigInt(10);      //10n
BigInt(true);    //1n

无法转换的数据类型和值会引发异常

BigInt(10.2);     //RangeError
BigInt(null);     //TypeError
BigInt("abc");    //SyntaxError

可以直接对使用构造函数创建的BigInt执行算术操作

BigInt(10) * 10n;    //100n

在使用严格相等运算符时,使用构造函数创建的BigInt 与常规BigInt 的处理方式类似

BigInt(true) === 1n;    //true
console.log( 1n == true) //true

BigInt 也可以用二进制,八进制或十六进制表示

// binary 二进制
console.log(0b100000000000000000000000000000000000000000000000000011n); 
//9007199254740995n

// hex 十六进制
console.log(0x20000000000003n);
//9007199254740995n

// octal 八进制
console.log(0o400000000000000003n);
//9007199254740995n

// 注意,不支持遗留的八进制语法
console.log(0400000000000000003n);
//SyntaxError 语法错误

不能使用严格相等运算符将BigInt与常规数字进行比较,因为它们的类型不同, 如下:

console.log(1n === 1); //false

console.log(typeof 10n); //bigint

console.log(typeof 10); //number

但在使用等号运算符,它在处理操作之前执行隐式转换

console.log(1n == 1); //true

除了一元加号(+)运算符外,所有的算术运算符都可以用于BigInt

1n + 20;  //3n
1n - 2n;  //-1n
+10n;     //语法错误   
//TypeError: Cannot convert a BigInt value 
//to a number:不能将BigInt值转换为数字
-1n;      //-1n
1n * 2n;  //2n
2n / 2n;  //1n
10n % 3n;  //1n
10n ** 2n;  //100n

var a = 1n;
++a;          //2n
--a;          //0n