Skip to main content

JavaScript BigInt

In this lesson, we'll explore JavaScript's BigInt - a built-in object introduced in ES2020 (ES11) that allows you to work with integers of arbitrary precision. Before BigInt, JavaScript could only safely represent numbers between -(2^53 - 1) and (2^53 - 1). But now, we can work with much larger numbers!

Introduction to BigInt

JavaScript traditionally has a single numeric type called Number which can represent integers and floating-point values. However, the Number type has limitations when dealing with very large integers.

Let's look at the maximum safe integer in JavaScript:

javascript
console.log(Number.MAX_SAFE_INTEGER); // 9007199254740991

This number (9007199254740991 or 2^53 - 1) represents the largest integer JavaScript can reliably represent with the Number primitive. Beyond this limit, precision becomes a problem.

For example:

javascript
console.log(9007199254740991); // 9007199254740991 (correct)
console.log(9007199254740991 + 1); // 9007199254740992 (correct)
console.log(9007199254740991 + 2); // 9007199254740992 (incorrect! should be 9007199254740993)

This is where BigInt comes to the rescue.

Creating BigInt Values

There are two ways to create a BigInt:

  1. Append the letter n to the end of an integer literal:
javascript
const bigInt = 9007199254740991n;
console.log(bigInt); // 9007199254740991n
  1. Call the BigInt() constructor:
javascript
const bigInt1 = BigInt(9007199254740991);
const bigInt2 = BigInt("9007199254740991");
console.log(bigInt1); // 9007199254740991n
console.log(bigInt2); // 9007199254740991n

Working with BigInt

Let's explore the basic operations and characteristics of BigInt:

Type Checking

BigInt is a separate primitive type:

javascript
const regularNum = 42;
const bigIntNum = 42n;

console.log(typeof regularNum); // "number"
console.log(typeof bigIntNum); // "bigint"

Arithmetic Operations

You can perform basic arithmetic operations with BigInt:

javascript
const a = 1234567890123456789n;
const b = 987654321987654321n;

console.log(a + b); // 2222222212111111110n
console.log(a - b); // 246913568135802468n
console.log(a * b); // 1219326312466898976304909138238409969n
console.log(a / b); // 1n (division truncates towards zero)
console.log(a % b); // 246913568135802468n
console.log(a ** 2n); // 1524157875323883675049535156256668161n

Comparison Operations

BigInt values can be compared using the usual comparison operators:

javascript
console.log(1n < 2n); // true
console.log(2n > 1n); // true
console.log(2n >= 2n); // true
console.log(2n <= 2n); // true
console.log(2n === 2n); // true

Mixing BigInt with Number

Mixing BigInt and regular Number in operations is not allowed and will throw a TypeError:

javascript
// This will throw a TypeError
try {
const result = 1n + 2;
console.log(result);
} catch (error) {
console.log(error.message); // "Cannot mix BigInt and other types"
}

You need to explicitly convert between types:

javascript
const bigIntValue = 5n;
const numberValue = 10;

// Convert Number to BigInt
console.log(bigIntValue + BigInt(numberValue)); // 15n

// Convert BigInt to Number (potential precision loss)
console.log(Number(bigIntValue) + numberValue); // 15

Equality Comparisons

When comparing BigInt with Number using loose equality (==), the comparison works as expected:

javascript
console.log(1n == 1); // true (loose equality)
console.log(1n === 1); // false (strict equality - different types)

Limitations

There are a few limitations when working with BigInt:

  1. No support for Math object methods:
javascript
// This will throw a TypeError
try {
console.log(Math.sqrt(4n));
} catch (error) {
console.log(error.message); // "Cannot convert a BigInt value to a number"
}
  1. Cannot mix with regular numbers in operations

  2. No decimal point operations - BigInt is for integers only:

javascript
// This will throw a RangeError
try {
console.log(5n / 2n); // Result is 2n, not 2.5n
console.log(BigInt(3.14)); // Error
} catch (error) {
console.log("Error: Cannot convert floating-point to BigInt");
}

Real-World Applications

Financial Calculations

BigInt is useful for precise financial calculations where large integers are needed:

javascript
// Calculate compound interest with large values
function calculateCompoundInterest(principal, ratePercent, years, compoundPerYear) {
const rate = BigInt(ratePercent);
const periods = BigInt(years) * BigInt(compoundPerYear);
const ratePerPeriod = rate * BigInt(10000) / BigInt(compoundPerYear) / BigInt(1000000);

// Calculate (1 + ratePerPeriod)^periods
// Using a simplified approach for demonstration
let base = BigInt(10000000) + ratePerPeriod;
let result = BigInt(10000000); // Represents 1.0 with 7 decimal precision

for (let i = 0; i < periods; i++) {
// Multiply and maintain precision
result = (result * base) / BigInt(10000000);
}

return (principal * result) / BigInt(10000000);
}

const principal = BigInt(10000000000); // $10 billion
const result = calculateCompoundInterest(principal, 5, 30, 12);
console.log(`After 30 years: $${result}`);

Cryptography

BigInt is essential for cryptographic operations that require large integers:

javascript
// Simple example of RSA-like calculation (not actual encryption)
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 / 2n;
base = (base * base) % modulus;
}

return result;
}

const message = 123456789n;
const publicKey = 65537n;
const modulus = 2349082340928409238409283409820948209480928409283409283409823098n;

const encrypted = modPow(message, publicKey, modulus);
console.log("Encrypted:", encrypted);

Managing Database IDs

When working with large database IDs that exceed JavaScript's safe integer limit:

javascript
// Twitter's snowflake-like ID generation
function generateId(timestamp, workerId, sequence) {
// Convert all inputs to BigInt if they aren't already
const timestampBits = BigInt(timestamp);
const workerIdBits = BigInt(workerId);
const sequenceBits = BigInt(sequence);

// Bit shifting operations (using BigInt)
return (timestampBits << 22n) |
(workerIdBits << 12n) |
sequenceBits;
}

const id = generateId(Date.now(), 5, 12);
console.log("Generated ID:", id.toString());

Performance Considerations

BigInt operations are generally slower than regular Number operations, so use them only when necessary:

javascript
// Performance comparison example
function measureTime(fn, name) {
const start = performance.now();
fn();
const end = performance.now();
console.log(`${name} took ${end - start} ms`);
}

// Regular number calculation
measureTime(() => {
let result = 1;
for (let i = 0; i < 1000000; i++) {
result = (result * 123) % 10007;
}
}, "Regular Number");

// BigInt calculation
measureTime(() => {
let result = 1n;
for (let i = 0; i < 1000000; i++) {
result = (result * 123n) % 10007n;
}
}, "BigInt");

Browser and Environment Support

BigInt is supported in all modern browsers and Node.js environments but may not be available in older browsers. Always check compatibility before using it in production.

javascript
// Feature detection
function supportsBigInt() {
return typeof BigInt === 'function';
}

if (supportsBigInt()) {
console.log("BigInt is supported!");
const reallyBigNumber = 9007199254740991n * 9007199254740991n;
console.log(reallyBigNumber);
} else {
console.log("BigInt is not supported in this environment");
}

Summary

JavaScript's BigInt provides a way to represent integers of arbitrary precision, which is crucial for situations where you need to work with numbers larger than Number.MAX_SAFE_INTEGER. Key points to remember:

  • Create BigInt values by appending n to integer literals or using the BigInt() constructor
  • BigInt is a distinct primitive type with its own operators and restrictions
  • You cannot mix BigInt and Number in operations without explicit conversion
  • BigInt can't represent fractions or decimals
  • Use it for financial calculations, cryptography, and other applications requiring precise integer arithmetic with large numbers
  • Be aware of performance implications when using BigInt for intensive calculations

Additional Resources

Exercises

  1. Calculate 2 raised to the power of 100 using BigInt and compare it with the result using regular Number.
  2. Write a function to determine if a BigInt is prime.
  3. Implement a factorial function that handles very large numbers using BigInt.
  4. Convert between binary, hexadecimal, and decimal representations using BigInt.
  5. Create a function to compute Fibonacci numbers with large indices using BigInt.

Happy coding with JavaScript's BigInt!



If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)