前端开发 / TypeScript BigInt

TypeScript BigInt

本节介绍的 bigint 数据类型是用来表示那些已经超出了 number 类型最大值的整数值,对于总是被诟病的整数溢出问题,使用了 bigint 后将完美解决。

1. 慕课解释

bigint 是一种基本数据类型(primitive data type)。

JavaScript 中可以用 Number 表示的最大整数为 2^53 - 1,可以写为 Number.MAX_SAFE_INTEGER。如果超过了这个界限,可以用 BigInt来表示,它可以表示任意大的整数。

2. 语法

在一个整数字面量后加 n 的方式定义一个 BigInt,如:10n 或者调用函数 BigInt()

const theBiggestInt: bigint = 9007199254740991n
const alsoHuge: bigint = BigInt(9007199254740991)
const hugeString: bigint = BigInt("9007199254740991")

theBiggestInt === alsoHuge // true
theBiggestInt === hugeString // true

代码解释:

第 1-3 行,分别是三种表达整数 9007199254740991 的方式,方式不同含义相同,所以完全相等。

BigIntNumber 的不同点:

  • BigInt 不能用于 Math 对象中的方法。
  • BigInt 不能和任何 Number 实例混合运算,两者必须转换成同一种类型。
  • BigInt 变量在转换为 Number 变量时可能会丢失精度。
const biggest: number = Number.MAX_SAFE_INTEGER

const biggest1: number = biggest + 1
const biggest2: number = biggest + 2

biggest1 === biggest2 // true 超过精度

代码解释:

第 1 行,声明了一个 number 类型最大值的变量 biggest,对于 number 类型来说,这个就是最大精度。

第 3-4 行,最大精度就是这个容器已经完全满了,无论往上加多少都会溢出,所以这两个值是相等的。

而使用 BigInt:

const biggest: bigint = BigInt(Number.MAX_SAFE_INTEGER)

const biggest1: bigint = biggest + 1n
const biggest2: bigint = biggest + 2n

biggest1 === biggest2 // false

代码解释:

第 1 行,声明了一个 bigint 类型的变量 biggest

第 3-4 行,bigint 类型就是用来表示那些已经超出了 number 类型最大值的整数值,也就是这个容器还没满,在此基础上加上两个不同的值,其结果不相等。

3. 类型信息

使用 typeof 检测类型时,BigInt 对象返回 bigint:

typeof 10n === 'bigint'         // true
typeof BigInt(10) === 'bigint'  // true

typeof 10 === 'number'          // true
typeof Number(10) === 'number'  // true

代码解释:

typeof 操作符返回一个字符串,表示未经计算的操作数的类型,用来判断基础数据类型。

第 1-2 行,两个书写方式都是 bigint 类型,所以相等。

第 4-5 行,两种书写方式都是 number 类型,所以相等。

4. 运算

BigInt 可以正常使用 +-*/**% 符号进行运算:

const previousMaxSafe: bigint = BigInt(Number.MAX_SAFE_INTEGER)  // 9007199254740991n

const maxPlusOne: bigint = previousMaxSafe + 1n                  // 9007199254740992n

const multi: bigint = previousMaxSafe * 2n                       // 18014398509481982n

const subtr: bigint = multi – 10n                                // 18014398509481972n

const mod: bigint = multi % 10n                                  // 2n

const bigN: bigint = 2n ** 54n                                   // 18014398509481984n

Tip: 当使用 / 操作符时,会向下取整,不会返回小数部分:

const divided: bigint = 5n / 2n                                   // 2n, not 2.5n

5. 比较 与 条件

NumberBigInt 可以进行比较:

0n === 0 // false

0n == 0 // true

1n < 2  // true

2n > 1  // true

2 > 2   // false

2n > 2  // false

2n >= 2 // true

条件判断:

if (0n) {
  console.log('条件成立!');
} else {
  console.log('条件不成立!'); // 输出结果
}

0n || 10n    // 10n

0n && 10n    // 0n

Boolean(0n)  // false

Boolean(10n) // true

!10n         // false

!0n          // true

代码解释:

后面会有一节介绍 Truthy 与 Falsy,这里先简单提下。除了明确的 true 和 false 两个 boolean 类型外,JavaScript 可以在需要用到布尔类型值的上下文中使用强制类型转换将值转换为布尔值。

比如 0 是假,10 是真。那么,同样的,0n 是假,10n 是真。

6. 小结

本小节介绍了 BigInt 类型相关知识,由于在 NumberBigInt 之间进行转换会损失精度,建议:

  • 不要在两种类型之间进行相互转换。
  • 仅在值可能大于 2^53 - 1 时使用 BigInt