◆

JavaScript BigInt 大整数类型详解

2023-02-02 01:370

概述

  • 什么是 BigInt?
  • BigInt 是一种内置对象,它提供了一种方法来表示大于 2 的 53 次方 - 1 的整数。这原本是 Javascript 中可以用 Number 表示的最大数字。
  • BigInt 可以表示任意大的整数。

为什么需要 BigInt?

在 JS 中,所有的数字都以双精度 64 位浮点格式表示,那这会带来什么问题呢?

这导致 JS 中的 Number 无法精确表示非常大的整数,它会将非常大的整数四舍五入, 确切地说,JS 中的 Number 类型只能安全地表示 -9007199254740991(-(2^53-1)) 和 9007199254740991((2^53-1)),任何超出此范围的整数值都可能失去精度。

同时也会有一定的安全性问题:

如何创建并使用 BigInt?

  • 要创建 BigInt,只需要在数字末尾追加 n 即可。
  • 另一种创建 BigInt 的方法是用 BigInt() 构造函数

示例

10n + 20n; // 30n
10n - 20n; // -10n
+10n; // TypeError: Cannot convert a BigInt value to a number
// BigInt不支持一元加号运算符, 这可能是某些程序可能依赖于 + 始终生成 Number 的不变量,或者抛出异常。
-10n; // -10n
10n * 20n; // 200n
20n / 10n; // 2n
23n % 10n; // 3n
10n ** 3n; // 1000n
const x = 10n;
++x; // 11n
--x; // 9n
console.log(typeof x); //"bigint"

它在某些方面类似于 Number ,但是也有几个关键的不同点:不能用与 Math 对象中的方法

Math.floor(1.1) // 1
Math.floor(1.1
n
) // Uncaught SyntaxError: Invalid or unexpected token

不能和任何 Number 实例(隐式类型转换可能丢失信息)混合运算,两者必须转换成同一种类型。 在两种类型来回转换时要小心,因为 BigInt 变量在转换成 Number 变量时可能会丢失精度。

1 + 2n // Uncaught TypeError: Cannot mix BigInt and other types, use explicit conversions
1n + 2n = 3n
1 + Number(2n) = 3
  • 当使用 BigInt 时,带小数的运算会被取整。
const rounded = 5n / 2n;
// 2n, not 2.5n
  • 使用 typeof 测试时, BigInt 对象返回 bigint :
typeof 1n === 'bigint'; // true
typeof BigInt('1') === 'bigint'; // true
  • 使用 Object 包装后, BigInt 被认为时一个普通 "object" :
typeof Object(1n) === 'object'; // true
  • BigInt 和 Number 不是严格相等的,但是宽松相等的。
0n === 0;
// false

0n == 0;
// true
  • Number 和 BigInt 可以进行比较。
1n < 2; // true
2n > 1; // true
2 > 2; // false
2n > 2; // false
2n >= 2; // true
  • 两者也可以混在一个数组内并排序。
const mixed = [4n, 6, -12n, 10, 4, 0, 0n];
//  [4n, 6, -12n, 10, 4, 0, 0n]

mixed.sort();
// [-12n, 0, 0n, 10, 4n, 4, 6]
  • 当 Boolean 类型与 BigInt 类型相遇时,BigInt 的处理方式与 Number 类似,换句话说,只要不是 0n,BigInt 就被视为 truthy 的值。
if (0n) {
  // 条件判断为false
  console.log('false');
}
if (3n) {
  // 条件为true
  console.log('true');
}
// 输出true

BigInt 可以使用负号(-),但是不能使用正号(+),因为会与 asm.js 冲突。

一元运算符 + 在 asm.js 里面总是返回 Number 类型,为了不破坏 asm.js 就规定 +1n 会报错。

-42n + // 正确
  42n; // 报错

BigInt 函数

可以用它生成 BigInt 类型的数值。转换规则基本与 Number() 一致,将其他类型的值转为 BigInt

BigInt(123); // 123n
BigInt('123'); // 123n
BigInt(false); // 0n
BigInt(true); // 1n

BigInt() 函数必须有参数,而且参数必须可以正常转为数值,下面的用法都会报错。参数如果是小数,也会报错。

new BigInt(); // TypeError
BigInt(undefined); // TypeError
BigInt(null); // TypeError
BigInt('123n'); // SyntaxError
BigInt('abc'); // SyntaxError
BigInt(1.5); // RangeError
BigInt('1.5'); // SyntaxError

BigInt 继承了 Object 对象的两个实例方法,继承了 Number 对象的一个实例方法

  • BigInt.prototype.toString()
  • BigInt.prototype.valueOf()
  • BigInt.prototype.toLocaleString()

提供了三个静态方法

  • BigInt.asUintN(width, BigInt): 给定的 BigInt 转为 0 到 2^width - 1 之间对应的值。
  • BigInt.asIntN(width, BigInt):给定的 BigInt 转为 -2^width - 1 到 2^(width - 1) - 1 之间对应的值。
  • BigInt.parseInt(string[, radix]):近似于 Number.parseInt(),将一个字符串转换成指定进制的 BigInt。
const max = 2n ** (64n - 1n) - 1n;

BigInt.asIntN(64, max);
// 9223372036854775807n
BigInt.asIntN(64, max + 1n);
// -9223372036854775808n
BigInt.asUintN(64, max + 1n);
// 9223372036854775808n

数据转换

Boolean(0n); // false
Boolean(1n); // true
Number(1n); // 1
String(1n); // "1"
!0n; // true
!1n; // false

// 与字符串混合运算时,会先转为字符串,再进行运算。
'' + 123n; // "123"
💬留言板0

还没有留言,来发表第一条吧~

PAGE LOAD / LIVEJavaScript BigInt 大整数类型详解加载中