阿里云主机折上折
  • 微信号
您当前的位置:网站首页 > BigInt原始数据类型

BigInt原始数据类型

作者:陈川 阅读数:57304人阅读 分类: JavaScript

ECMAScript 10引入了BigInt原始数据类型,用于表示任意精度的整数。它解决了Number类型无法精确表示大于2^53 - 1或小于-(2^53 - 1)的整数的问题,为数学运算和大整数处理提供了原生支持。

BigInt的基本概念

BigInt是一种新的原始数据类型,与Number类型并列。它的值可以通过在整数末尾添加n或调用BigInt()构造函数来创建。例如:

const bigInt1 = 123456789012345678901234567890n;
const bigInt2 = BigInt("123456789012345678901234567890");

BigIntNumber类型的主要区别在于:

  1. 存储范围:BigInt可以表示任意大的整数,而Number的整数范围受IEEE 754双精度浮点数限制
  2. 类型判断:typeof操作符对BigInt返回"bigint"
  3. 运算限制:BigInt不能与Number直接混合运算

BigInt的创建方式

创建BigInt主要有两种方式:

  1. 字面量表示法:直接在数字后面加n
const a = 10n;
const b = -0x1an; // 十六进制表示
const c = 0o777n; // 八进制表示
  1. 使用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特别适合以下场景:

  1. 高精度时间戳处理
const nanoTime = 1640995200000000000n; // 纳秒级时间戳
const milliseconds = nanoTime / 1000000n; // 转换为毫秒
  1. 大整数ID处理
const userId = 9007199254740993n; // 超过Number安全范围的ID
  1. 加密算法实现
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时需要注意以下限制:

  1. JSON序列化问题
const obj = { id: 123n };
// JSON.stringify(obj); // TypeError
// 解决方案
const jsonStr = JSON.stringify(obj, (key, value) => 
  typeof value === 'bigint' ? value.toString() : value
);
  1. 不能使用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;
}
  1. 浏览器兼容性检查
if (typeof BigInt === 'undefined') {
  console.log('当前环境不支持BigInt');
  // 使用polyfill或替代方案
}

BigInt的性能考量

虽然BigInt提供了大整数支持,但性能上需要注意:

  1. 运算速度通常比Number
  2. 内存占用更高
  3. 频繁的类型转换会影响性能

性能测试示例:

// 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的进阶用法

  1. 实现大整数阶乘
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
  1. 斐波那契数列计算
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
  1. 大素数检测
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

前端川

前端川,陈川的代码茶馆🍵,专治各种不服的Bug退散符💻,日常贩卖秃头警告级的开发心得🛠️,附赠一行代码笑十年的摸鱼宝典🐟,偶尔掉落咖啡杯里泡开的像素级浪漫☕。‌