BigInt原始数据类型
ECMAScript 10引入了BigInt
原始数据类型,用于表示任意精度的整数。它解决了Number
类型无法精确表示大于2^53 - 1
或小于-(2^53 - 1)
的整数的问题,为数学运算和大整数处理提供了原生支持。
BigInt的基本概念
BigInt
是一种新的原始数据类型,与Number
类型并列。它的值可以通过在整数末尾添加n
或调用BigInt()
构造函数来创建。例如:
const bigInt1 = 123456789012345678901234567890n;
const bigInt2 = BigInt("123456789012345678901234567890");
BigInt
与Number
类型的主要区别在于:
- 存储范围:
BigInt
可以表示任意大的整数,而Number
的整数范围受IEEE 754双精度浮点数限制 - 类型判断:
typeof
操作符对BigInt
返回"bigint"
- 运算限制:
BigInt
不能与Number
直接混合运算
BigInt的创建方式
创建BigInt
主要有两种方式:
- 字面量表示法:直接在数字后面加
n
const a = 10n;
const b = -0x1an; // 十六进制表示
const c = 0o777n; // 八进制表示
- 使用
BigInt()
构造函数:
const d = BigInt(123);
const e = BigInt("12345678901234567890");
const f = BigInt(true); // 等同于1n
需要注意的是,使用构造函数时:
- 传入非整数值会抛出
RangeError
- 传入非数值类型会先尝试转换为数字
BigInt的运算特性
BigInt
支持大多数数学运算,但有一些特殊规则:
// 基本算术运算
const x = 10n;
const y = 3n;
console.log(x + y); // 13n
console.log(x - y); // 7n
console.log(x * y); // 30n
console.log(x / y); // 3n (截断小数部分)
console.log(x % y); // 1n
// 比较运算
console.log(10n === 10); // false (类型不同)
console.log(10n == 10); // true (值相等)
console.log(10n > 5); // true
// 位运算
console.log(5n & 3n); // 1n
console.log(5n | 3n); // 7n
console.log(5n ^ 3n); // 6n
console.log(~5n); // -6n
BigInt与Number的交互
BigInt
不能直接与Number
混合运算,需要显式转换:
const big = 100n;
const num = 50;
// 错误示例
// console.log(big + num); // TypeError
// 正确做法
console.log(big + BigInt(num)); // 150n
console.log(Number(big) + num); // 150
类型转换时需要注意:
BigInt
转换为Number
可能导致精度丢失- 负零(
-0n
)转换为Number
会变成0
BigInt的API方法
BigInt
提供了一些实用的静态方法:
// 判断是否为有效BigInt值
console.log(BigInt.asIntN(64, 12345678901234567890n)); // 12345678901234567890n
// 限制位数
console.log(BigInt.asIntN(32, 1234567890n)); // 1234567890n
console.log(BigInt.asUintN(32, -1n)); // 4294967295n
// 最大值/最小值
const max64 = 2n ** 63n - 1n;
const min64 = -(2n ** 63n);
BigInt的实际应用场景
BigInt
特别适合以下场景:
- 高精度时间戳处理
const nanoTime = 1640995200000000000n; // 纳秒级时间戳
const milliseconds = nanoTime / 1000000n; // 转换为毫秒
- 大整数ID处理
const userId = 9007199254740993n; // 超过Number安全范围的ID
- 加密算法实现
function modExp(base, exponent, modulus) {
let result = 1n;
base = base % modulus;
while (exponent > 0n) {
if (exponent % 2n === 1n) {
result = (result * base) % modulus;
}
exponent = exponent >> 1n;
base = (base * base) % modulus;
}
return result;
}
BigInt的注意事项
使用BigInt
时需要注意以下限制:
- JSON序列化问题
const obj = { id: 123n };
// JSON.stringify(obj); // TypeError
// 解决方案
const jsonStr = JSON.stringify(obj, (key, value) =>
typeof value === 'bigint' ? value.toString() : value
);
- 不能使用
Math
对象的方法
// Math.sqrt(16n); // TypeError
// 替代方案
function bigIntSqrt(value) {
if (value < 0n) throw new Error("负数没有实数平方根");
if (value < 2n) return value;
let x = value / 2n;
while (x * x > value) {
x = ((value / x) + x) / 2n;
}
return x;
}
- 浏览器兼容性检查
if (typeof BigInt === 'undefined') {
console.log('当前环境不支持BigInt');
// 使用polyfill或替代方案
}
BigInt的性能考量
虽然BigInt
提供了大整数支持,但性能上需要注意:
- 运算速度通常比
Number
慢 - 内存占用更高
- 频繁的类型转换会影响性能
性能测试示例:
// Number运算
console.time('Number');
let numSum = 0;
for (let i = 0; i < 1000000; i++) {
numSum += i;
}
console.timeEnd('Number');
// BigInt运算
console.time('BigInt');
let bigSum = 0n;
for (let i = 0n; i < 1000000n; i++) {
bigSum += i;
}
console.timeEnd('BigInt');
BigInt的进阶用法
- 实现大整数阶乘
function factorial(n) {
if (n < 0n) throw new Error("负数没有阶乘");
let result = 1n;
for (let i = 2n; i <= n; i++) {
result *= i;
}
return result;
}
console.log(factorial(100n)); // 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000n
- 斐波那契数列计算
function fibonacci(n) {
let a = 0n, b = 1n;
for (let i = 0n; i < n; i++) {
[a, b] = [b, a + b];
}
return a;
}
console.log(fibonacci(100n)); // 354224848179261915075n
- 大素数检测
function isPrime(n) {
if (n <= 1n) return false;
if (n <= 3n) return true;
if (n % 2n === 0n || n % 3n === 0n) return false;
let i = 5n;
while (i * i <= n) {
if (n % i === 0n || n % (i + 2n) === 0n) return false;
i += 6n;
}
return true;
}
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn
上一篇:Function.prototype.toString()改进
下一篇:动态导入