JavaScript BigInt 类型

定义

BigInt 是ES2020引入的JavaScript原始数据类型,用于表示任意精度的整数,突破了Number类型的安全整数范围限制。

创建 BigInt

字面量语法

// 在整数后加 'n'
const bigInt1 = 123n;
const bigInt2 = 9007199254740992n;
 
// 二进制、八进制、十六进制
const binary = 0b1010n;      // 二进制
const octal = 0o777n;        // 八进制  
const hex = 0xFFn;          // 十六进制

BigInt() 构造函数

// 从数字创建
const fromNumber = BigInt(123);       // 123n
const fromString = BigInt("456");     // 456n
 
// 注意:不能传入小数
// BigInt(3.14);  // TypeError
 
// 处理大数字字符串
const largeNum = BigInt("9007199254740993");

使用场景

1. 超大整数计算

// Number类型的限制
console.log(Number.MAX_SAFE_INTEGER);  // 9007199254740991
console.log(Number.MAX_SAFE_INTEGER + 1);  // 9007199254740992
console.log(Number.MAX_SAFE_INTEGER + 2);  // 9007199254740992(精度丢失)
 
// 使用BigInt
const maxSafe = BigInt(Number.MAX_SAFE_INTEGER);
console.log(maxSafe + 1n);  // 9007199254740992n
console.log(maxSafe + 2n);  // 9007199254740993n(精确)

2. 高精度时间戳

// 微秒级时间戳
const microsecondTimestamp = BigInt(Date.now()) * 1000n;
console.log(microsecondTimestamp);
 
// 纳秒级时间戳  
const nanosecondTimestamp = BigInt(Date.now()) * 1000000n;

3. 加密和哈希算法

// RSA 密钥计算示例
function modPow(base, exponent, modulus) {
    if (modulus === 1n) return 0n;
    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;
}

4. 金融计算

// 避免浮点数精度问题
function calculateInterest(principal, rate, time) {
    // 转换为分(避免小数)
    const principalCents = BigInt(Math.round(principal * 100));
    const ratePercent = BigInt(Math.round(rate * 10000));
    const timeMonths = BigInt(time);
    
    const interest = (principalCents * ratePercent * timeMonths) / (10000n * 12n);
    return Number(interest) / 100;  // 转回元
}

运算操作

算术运算

const a = 10n;
const b = 3n;
 
console.log(a + b);    // 13n
console.log(a - b);    // 7n
console.log(a * b);    // 30n
console.log(a / b);    // 3n(整数除法)
console.log(a % b);    // 1n
console.log(a ** b);   // 1000n(幂运算)

位运算

const x = 12n;  // 二进制: 1100
const y = 10n;  // 二进制: 1010
 
console.log(x & y);   // 8n  (1000)
console.log(x | y);   // 14n (1110)  
console.log(x ^ y);   // 6n  (0110)
console.log(~x);      // -13n
console.log(x << 2n); // 48n (左移)
console.log(x >> 1n); // 6n  (右移)

比较运算

console.log(10n > 5n);    // true
console.log(10n === 10n); // true
console.log(10n == 10);   // true(类型转换)
console.log(10n === 10);  // false(严格比较)
 
// 与Number的比较
console.log(10n > 9);     // true
console.log(10n < 11);    // true

类型转换

BigInt 转其他类型

const bigNum = 123n;
 
// 转换为Number(注意精度丢失)
console.log(Number(bigNum));    // 123
 
// 转换为String
console.log(String(bigNum));    // "123"
console.log(bigNum.toString()); // "123"
console.log(bigNum.toString(16)); // "7b"(十六进制)
 
// 转换为Boolean
console.log(Boolean(0n));       // false
console.log(Boolean(1n));       // true

其他类型转BigInt

// Number转BigInt(必须是整数)
console.log(BigInt(42));        // 42n
// console.log(BigInt(3.14));   // TypeError
 
// String转BigInt
console.log(BigInt("123"));     // 123n
console.log(BigInt("0xFF"));    // 255n
// console.log(BigInt("abc"));  // SyntaxError
 
// Boolean转BigInt
console.log(BigInt(true));      // 1n
console.log(BigInt(false));     // 0n

限制和注意事项

1. 不能与Number混合运算

const bigInt = 10n;
const number = 5;
 
// 错误的操作
// console.log(bigInt + number);     // TypeError
// console.log(bigInt * number);     // TypeError
 
// 正确的操作
console.log(bigInt + BigInt(number)); // 15n
console.log(Number(bigInt) + number); // 15

2. Math对象不支持BigInt

// Math.max(10n, 20n);  // TypeError
// Math.sqrt(25n);      // TypeError
 
// 需要自定义函数
function bigIntMax(a, b) {
    return a > b ? a : b;
}

3. JSON序列化问题

const data = { id: 123n, name: "test" };
 
// 默认情况下会报错
// JSON.stringify(data);  // TypeError
 
// 需要自定义序列化
JSON.stringify(data, (key, value) =>
    typeof value === 'bigint' ? value.toString() : value
);
// "{"id":"123","name":"test"}"

性能考虑

1. 内存使用

// BigInt使用更多内存
const numbers = Array(1000000).fill(0).map((_, i) => i);
const bigInts = Array(1000000).fill(0).map((_, i) => BigInt(i));
 
console.log('Numbers memory usage is lower');
console.log('BigInts memory usage is higher');

2. 计算性能

// 性能测试示例
function performanceTest() {
    const iterations = 1000000;
    
    // Number运算
    console.time('Number operations');
    for (let i = 0; i < iterations; i++) {
        let result = i * 2 + 1;
    }
    console.timeEnd('Number operations');
    
    // BigInt运算  
    console.time('BigInt operations');
    for (let i = 0n; i < BigInt(iterations); i++) {
        let result = i * 2n + 1n;
    }
    console.timeEnd('BigInt operations');
}

实际应用示例

斐波那契数列(大数版本)

function fibonacciBigInt(n) {
    if (n <= 1n) return n;
    
    let a = 0n;
    let b = 1n;
    
    for (let i = 2n; i <= n; i++) {
        [a, b] = [b, a + b];
    }
    
    return b;
}
 
console.log(fibonacciBigInt(100n));  // 计算第100个斐波那契数

大整数阶乘

function factorialBigInt(n) {
    if (n <= 1n) return 1n;
    
    let result = 1n;
    for (let i = 2n; i <= n; i++) {
        result *= i;
    }
    
    return result;
}
 
console.log(factorialBigInt(50n));  // 50的阶乘

兼容性和检测

浏览器支持检测

function supportsBigInt() {
    return typeof BigInt !== 'undefined';
}
 
if (supportsBigInt()) {
    console.log('浏览器支持BigInt');
} else {
    console.log('浏览器不支持BigInt,需要polyfill');
}

类型检测

function isBigInt(value) {
    return typeof value === 'bigint';
}
 
console.log(isBigInt(123n));    // true
console.log(isBigInt(123));     // false
console.log(isBigInt("123"));   // false

下一篇:String 类型