什么是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
类型检测
因为BigInt是一个原始类型,因此可以使用typeof 检测到类型
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的不同
1. 和Number不同,BigInt()没有参数时,会报TypeError,但是Number()返回0。
Number() // 0 BigInt() // Uncaught TypeError
2. 当非数字时, 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
3. 对于-0的处理不同
Number(-0) === -0 BigInt(-0) === 0n
4. 两者都会把true变为1,false变为0
Number(true) === 1 Number(false) === 0 BigInt(true) === 1n BigInt(false) === 0n
5. 对于浮点数, BigInt 抛出 RangeError 异常
BigInt(4.00000001) // Uncaught RangeError Number(4.00000001) // 4.00000001
6. 对于 NaN 和正负无穷, BigInt 抛出 RangeError 异常
BigInt(NaN) // RangeError BigInt(-Infinity) // RangeError BigInt(+Infinity) // RangeError Number(NaN) // NaN Number(-Infinity) // -Infinity Number(Infinity) // Infinity
7. BigInt不能隐式转换为 Number,所以在接受 Number作为参数的运算中,将抛出 TypeError异常
isNaN(0n) // TypeError isFinite(0n) // TypeError Math.abs(-4n) // TypeError "bar".substr(1n) // TypeError
8.部分运算可以使用
Number.isSafeInteger(0n) === false Number.isFinite(0n) === false Number.isNaN(0n) === false Number.parseInt(0n) === 0
9. 因为 BigInt表示的是整数,所以只存在一个 0(无正零和负零之分)
Object.is(-0, 0) === false Object.is(-0n, 0n) === true
10. 由于 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.asIntN(width, value):包含-2**(width-1) ~ 2**(width-1)-1 之间的值,包含符号
BigInt.asUintN(): 0 and 2**(width-1)
注意
在Number和
BigInt间强制转换,
可能导致精度损失,所以建议仅BigInt
在合理预期大于2**53的值时使用,而不是在两种类型之间强制使用
BigInt
因此不适用于密码学。BigInt只适用于整数