Blog
Blog copied to clipboard
BigInt
什么是BigInt
js的number是双精度浮点数,安全范围为 2^53 到 -2^53,可以通过
Number.MAX_SAFE_INTEGER , Number.MIN_SAFE_INTEGER 获得具体数值,当初过安全范围时
let maxNum = 9007199254740991
maxNum + 1 // 9007199254740992
maxNum + 2 // 9007199254740992
maxNum + 3 // 9007199254740994
maxNum + 4 // 9007199254740996
maxNum + 5 // 9007199254740996
正常情况下,maxNum + 2 = 9007199254740993,但是超过安全范围后, 任何计算可能会失去精度,在javascript中,大整数ID和高精度的时间戳,没有办法很好的使用 number 类型表示,所以我们基本上会使用字符串来表示这些数字,但是发生计算时,会给开发者带来不便,现在有了 bigint 类型,我们就可以用来表示这些数值,也可以很方便的进行运算。
BigInt -- 是 JavaScript 中的一个新的 数字基本(primitive)类型,可以用任意精度表示整数。使用 BigInt 可以安全的存储和操作大整数,即使这个数超过了 Number 的安全整数范围。BigInt 我们可以执行正确的整数运算而不必担心失去精度。
创建一个BigInt
使用 BigInt(), 这里不需要 new,BigInt 只有函数,没有构造器,因此不能使用 new 来创建 BigInt 的实例
// 1.在后面直接添加 n
const firstBigInt = 9007199254740991n
// 2. 使用 BigInt(), 这里不需要 new, BigInt 只有函数,没有构造器,因此不能使用 new 来创建 BigInt 的实例
const secondBigInt = BigInt(9007199254740991) // 9007199254740991n
// 字符串
const thirdBigInt = BigInt("9007199254740991") // 9007199254740991n
// 16进制
const hugeHex = BigInt("0x1fffffffffffff") // 9007199254740991n
类型检测
typeof 12n = "bigint"
typeof BigInt(1) = "bigint"
// 当使用Object包装一下
typeof Object(1n) = "object"
比较
因为 BigInt 是单独的一个类型,所以 BigInt 和 number 并不完全相等,如果需要比较的话,可以转换成同一类型,或者使用 ==
2n === 2 // false
2n == 2 // true
2n === 2n // true
/* number 和 bigint可以照常比较 */
1 < 2n // true
2n >= 2n // true
2n > 2 // false
与Number的不同
// 和Number不同,BigInt()没有参数时,会报TypeError,但是Number()返回0
Number() // 0
BigInt() // Uncaught TypeError
// 当非数字时, Number 返回 NaN, BigInt 抛出 TypeError 或 SyntaxError
Number(undefined) // NaN
BigInt(undefined) // TypeError
Number(null) // 0
BigInt(null) // TypeError
Number({}) // NaN
BigInt({}) // SyntaxError
Number("foo") // NaN
BigInt("foo") // SyntaxError
// 对于-0的处理不同
Number(-0) === -0
BigInt(-0) === 0n
// 两者都会把true变为1,false变为0
Number(true) === 1
Number(false) === 0
BigInt(true) === 1n
BigInt(false) === 0n
// 对于浮点数, BigInt 抛出 RangeError 异常
BigInt(4.00000001) // Uncaught RangeError
Number(4.00000001) // 4.00000001
// 对于 NaN 和正负无穷, BigInt 抛出 RangeError 异常
BigInt(NaN) // RangeError
BigInt(-Infinity) // RangeError
BigInt(+Infinity) // RangeError
Number(NaN) // NaN
Number(-Infinity) // -Infinity
Number(Infinity) // Infinity
// BigInt不能隐式转换为 Number,所以在接受 Number作为参数的运算中,将抛出 TypeError异常
isNaN(0n) // TypeError
isFinite(0n) // TypeError
Math.abs(-4n) // TypeError
"bar".substr(1n) // TypeError
// 部分运算可以使用
Number.isSafeInteger(0n) === false
Number.isFinite(0n) === false
Number.isNaN(0n) === false
Number.parseInt(0n) === 0
// 因为 BigInt表示的是整数,所以只存在一个 0(无正零和负零之分)
Object.is(-0, 0) === false
Object.is(-0n, 0n) === true
// 由于 0和 0n不相等,所以在集合中,两者可以共存
let s = new Set([0, 0n]);
s.size === 2;
运算
BIgInt 支持常规的运算符,二元运算符 +,-,*,**,%,按位运算符:|,&,>>,<<,都与number 一致,运算时,不能与 number 混合运算
1n + 1n // 2n
1n + 1 // error
64n - 12n // 52n
2n * 2n // 4n
5n % 2n // 1n
2n ** 4n // 16n
1n << 5n // 32n
1n | 2n // 3n
1n & 2n // 0n
16n >> 2n // 4n
/* 比较运算符 */
if (0n) {
console.log("if")
} else {
console.log("else")
}
0n || 12n // 12n
0n && 12n // 0n
Boolean(0n) // false
Boolean(12n) // true
!12n // false
!0n // true
注意:/ 运算符与
number不同,有小数舍去 5n / 2n = 2n // 2.5 12n / 7n = 1n // 1.71
方法
将 BigInt 值封装为有符号或无符号整数,限于特定的位数 (64位),请注意,只要我们传递 BigInt 超过 64位 整数范围的值(例如,绝对数值为63位+符号为1位),就会发生溢出
bigInt.asIntN(width, value):包含-2^(width-1) ~ 2^(width-1)-1 之间的值,包含符号
BigInt.asUintN(): 0 and 2^(width-1)
注意
在
Number和BigInt间强制转换,可能导致精度损失,所以建议仅BigInt在合理预期大于2^53的值时使用,而不是在两种类型之间强制使用BigInt不适用于密码学。
BigInt只适用于整数
兼容浏览器情况
兼容情况