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:
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:
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
:
- Append the letter
n
to the end of an integer literal:
const bigInt = 9007199254740991n;
console.log(bigInt); // 9007199254740991n
- Call the
BigInt()
constructor:
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:
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
:
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:
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:
// 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:
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:
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
:
- No support for
Math
object methods:
// 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"
}
-
Cannot mix with regular numbers in operations
-
No decimal point operations -
BigInt
is for integers only:
// 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:
// 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:
// 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:
// 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:
// 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.
// 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 appendingn
to integer literals or using theBigInt()
constructor BigInt
is a distinct primitive type with its own operators and restrictions- You cannot mix
BigInt
andNumber
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
- MDN Web Docs: BigInt
- ECMAScript Proposal for BigInt
- V8 Blog: BigInt - Arbitrary Precision Integers in JavaScript
Exercises
- Calculate 2 raised to the power of 100 using
BigInt
and compare it with the result using regularNumber
. - Write a function to determine if a BigInt is prime.
- Implement a factorial function that handles very large numbers using
BigInt
. - Convert between binary, hexadecimal, and decimal representations using
BigInt
. - 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! :)