阿里云主机折上折
  • 微信号
Current Site:Index > The BigInt primitive data type

The BigInt primitive data type

Author:Chuan Chen 阅读数:57306人阅读 分类: JavaScript

ECMAScript 10 introduced the BigInt primitive data type for representing arbitrary-precision integers. It addresses the limitation of the Number type, which cannot precisely represent integers larger than 2^53 - 1 or smaller than -(2^53 - 1), providing native support for mathematical operations and large integer handling.

Basic Concepts of BigInt

BigInt is a new primitive data type, standing alongside the Number type. Its values can be created by appending n to an integer or by calling the BigInt() constructor. For example:

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

The main differences between BigInt and the Number type are:

  1. Storage range: BigInt can represent arbitrarily large integers, while Number's integer range is limited by IEEE 754 double-precision floating-point constraints.
  2. Type checking: The typeof operator returns "bigint" for BigInt.
  3. Operation restrictions: BigInt cannot be directly mixed with Number in operations.

Ways to Create BigInt

There are two primary ways to create BigInt:

  1. Literal notation: Append n directly to a number.
const a = 10n;
const b = -0x1an; // Hexadecimal representation
const c = 0o777n; // Octal representation
  1. Using the BigInt() constructor:
const d = BigInt(123);
const e = BigInt("12345678901234567890");
const f = BigInt(true); // Equivalent to 1n

Note the following when using the constructor:

  • Passing non-integer values will throw a RangeError.
  • Non-numeric types will first be attempted to be converted to numbers.

Operational Characteristics of BigInt

BigInt supports most mathematical operations but has some special rules:

// Basic arithmetic operations
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 (truncates the fractional part)
console.log(x % y); // 1n

// Comparison operations
console.log(10n === 10); // false (different types)
console.log(10n == 10); // true (equal values)
console.log(10n > 5); // true

// Bitwise operations
console.log(5n & 3n); // 1n
console.log(5n | 3n); // 7n
console.log(5n ^ 3n); // 6n
console.log(~5n); // -6n

Interaction Between BigInt and Number

BigInt cannot be directly mixed with Number in operations; explicit conversion is required:

const big = 100n;
const num = 50;

// Incorrect example
// console.log(big + num); // TypeError

// Correct approach
console.log(big + BigInt(num)); // 150n
console.log(Number(big) + num); // 150

Note the following during type conversion:

  • Converting BigInt to Number may result in precision loss.
  • Negative zero (-0n) converts to 0 in Number.

BigInt API Methods

BigInt provides some useful static methods:

// Check if it is a valid BigInt value
console.log(BigInt.asIntN(64, 12345678901234567890n)); // 12345678901234567890n

// Limit the number of bits
console.log(BigInt.asIntN(32, 1234567890n)); // 1234567890n
console.log(BigInt.asUintN(32, -1n)); // 4294967295n

// Maximum/Minimum values
const max64 = 2n ** 63n - 1n;
const min64 = -(2n ** 63n);

Practical Use Cases for BigInt

BigInt is particularly suitable for the following scenarios:

  1. High-precision timestamp handling:
const nanoTime = 1640995200000000000n; // Nanosecond-level timestamp
const milliseconds = nanoTime / 1000000n; // Convert to milliseconds
  1. Large integer ID handling:
const userId = 9007199254740993n; // ID exceeding the safe range of Number
  1. Cryptographic algorithm implementation:
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;
}

Considerations for Using BigInt

When using BigInt, be aware of the following limitations:

  1. JSON serialization issues:
const obj = { id: 123n };
// JSON.stringify(obj); // TypeError
// Solution
const jsonStr = JSON.stringify(obj, (key, value) => 
  typeof value === 'bigint' ? value.toString() : value
);
  1. Cannot use Math object methods:
// Math.sqrt(16n); // TypeError
// Alternative
function bigIntSqrt(value) {
  if (value < 0n) throw new Error("Negative numbers have no real square root");
  if (value < 2n) return value;
  
  let x = value / 2n;
  while (x * x > value) {
    x = ((value / x) + x) / 2n;
  }
  return x;
}
  1. Browser compatibility checks:
if (typeof BigInt === 'undefined') {
  console.log('BigInt is not supported in the current environment');
  // Use polyfill or alternative solutions
}

Performance Considerations for BigInt

Although BigInt provides support for large integers, performance should be considered:

  1. Operations are generally slower than with Number.
  2. Higher memory usage.
  3. Frequent type conversions can impact performance.

Performance test example:

// Number operations
console.time('Number');
let numSum = 0;
for (let i = 0; i < 1000000; i++) {
  numSum += i;
}
console.timeEnd('Number');

// BigInt operations
console.time('BigInt');
let bigSum = 0n;
for (let i = 0n; i < 1000000n; i++) {
  bigSum += i;
}
console.timeEnd('BigInt');

Advanced Usage of BigInt

  1. Implementing large integer factorial:
function factorial(n) {
  if (n < 0n) throw new Error("Negative numbers have no factorial");
  let result = 1n;
  for (let i = 2n; i <= n; i++) {
    result *= i;
  }
  return result;
}
console.log(factorial(100n)); // 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000n
  1. Fibonacci sequence calculation:
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. Large prime number detection:
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

Front End Chuan

Front End Chuan, Chen Chuan's Code Teahouse 🍵, specializing in exorcising all kinds of stubborn bugs 💻. Daily serving baldness-warning-level development insights 🛠️, with a bonus of one-liners that'll make you laugh for ten years 🐟. Occasionally drops pixel-perfect romance brewed in a coffee cup ☕.