8.3-BigInt
8.3 BigInt
Overview
BigInt is a built-in JavaScript primitive that provides a way to represent integers larger than the Number.MAX_SAFE_INTEGER (2^53 - 1). Introduced in ES2020, BigInt enables precise arithmetic operations on arbitrarily large integers without losing precision.
Learning Objectives
- •Understand the limitations of JavaScript Number type
- •Create and work with BigInt values
- •Perform arithmetic operations with BigInt
- •Convert between Number and BigInt
- •Use BigInt in practical applications
Why BigInt?
Number Limitations
// Safe integer range
console.log(Number.MAX_SAFE_INTEGER); // 9007199254740991
console.log(Number.MIN_SAFE_INTEGER); // -9007199254740991
// Loss of precision beyond safe range
console.log(9007199254740991 + 1); // 9007199254740992 ✓
console.log(9007199254740991 + 2); // 9007199254740992 ✗ (should be 9007199254740993)
console.log(9007199254740991 + 3); // 9007199254740994 ✗ (should be 9007199254740994)
// Check if safe
console.log(Number.isSafeInteger(9007199254740991)); // true
console.log(Number.isSafeInteger(9007199254740992)); // false
Creating BigInt Values
Literal Syntax
// Append 'n' to create BigInt literal
const big = 123456789012345678901234567890n;
console.log(big); // 123456789012345678901234567890n
console.log(typeof big); // "bigint"
// Negative BigInt
const negative = -9007199254740993n;
BigInt Constructor
// From integer
const fromInt = BigInt(123); // 123n
// From string (for very large numbers)
const fromString = BigInt('123456789012345678901234567890');
// From hex, octal, binary strings
const fromHex = BigInt('0xFF'); // 255n
const fromOctal = BigInt('0o777'); // 511n
const fromBinary = BigInt('0b11111111'); // 255n
Important Restrictions
// Cannot create from decimal/float
BigInt(1.5); // TypeError
BigInt(NaN); // TypeError
BigInt(Infinity); // TypeError
// Use Math.trunc for decimals
BigInt(Math.trunc(1.9)); // 1n
Arithmetic Operations
Basic Operations
const a = 10n;
const b = 3n;
console.log(a + b); // 13n (addition)
console.log(a - b); // 7n (subtraction)
console.log(a * b); // 30n (multiplication)
console.log(a / b); // 3n (division - truncated)
console.log(a % b); // 1n (remainder)
console.log(a ** b); // 1000n (exponentiation)
Division Behavior
// Division truncates toward zero
console.log(5n / 2n); // 2n (not 2.5)
console.log(-5n / 2n); // -2n (not -2.5)
// For decimal results, convert to Number
const result = Number(5n) / Number(2n); // 2.5
Unary Operations
const x = 5n;
console.log(-x); // -5n (negation works)
// console.log(+x); // TypeError (unary + not supported)
Comparison Operations
Equality
// Strict equality (type matters)
console.log(10n === 10); // false (different types)
console.log(10n === 10n); // true
// Loose equality (type coercion)
console.log(10n == 10); // true
console.log(10n == '10'); // true
Relational Comparisons
console.log(10n > 5n); // true
console.log(10n > 5); // true (mixed comparison allowed)
console.log(10n < 20); // true
// Sorting
const mixed = [10n, 5, 8n, 3, 12n];
mixed.sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));
console.log(mixed); // [3, 5, 8n, 10n, 12n]
Type Conversion
BigInt to Other Types
const big = 123n;
// To Number (may lose precision)
console.log(Number(big)); // 123
// To String
console.log(String(big)); // "123"
console.log(big.toString()); // "123"
console.log(big.toString(16)); // "7b" (hex)
console.log(big.toString(2)); // "1111011" (binary)
// To Boolean
console.log(Boolean(0n)); // false
console.log(Boolean(1n)); // true
Number to BigInt
// Safe integer
const num = 123;
const big = BigInt(num); // 123n
// Precision loss warning
const unsafe = 9007199254740993; // Already lost precision
console.log(BigInt(unsafe)); // 9007199254740992n (wrong!)
// Use string for large numbers
const correct = BigInt('9007199254740993'); // Correct!
Cannot Mix with Number
const big = 10n;
const num = 5;
// These throw TypeError
// big + num;
// big * num;
// Math.sqrt(big);
// Must convert explicitly
console.log(big + BigInt(num)); // 15n
console.log(Number(big) + num); // 15
BigInt with Built-in Objects
Array Methods
const bigInts = [10n, 5n, 20n, 15n];
// Some methods work
console.log(bigInts.includes(5n)); // true
// Sorting requires custom comparator
bigInts.sort((a, b) => {
if (a < b) return -1;
if (a > b) return 1;
return 0;
});
JSON
// BigInt is not JSON-serializable by default
const obj = { id: 123456789012345678901n };
// JSON.stringify(obj); // TypeError
// Custom serialization
const jsonString = JSON.stringify(obj, (key, value) =>
typeof value === 'bigint' ? value.toString() : value
);
console.log(jsonString); // {"id":"123456789012345678901"}
// Custom parsing
const parsed = JSON.parse(jsonString, (key, value) =>
key === 'id' ? BigInt(value) : value
);
Bitwise Operations
const a = 0b1010n; // 10n
const b = 0b1100n; // 12n
console.log(a & b); // 8n (0b1000) - AND
console.log(a | b); // 14n (0b1110) - OR
console.log(a ^ b); // 6n (0b0110) - XOR
console.log(~a); // -11n - NOT
// Shifts
console.log(a << 2n); // 40n (left shift)
console.log(a >> 1n); // 5n (right shift)
Practical Use Cases
Database IDs
// Many databases use 64-bit IDs
const twitterId = 1234567890123456789n;
const snowflakeId = BigInt('1309881276729737216');
// Safe to compare and manipulate
const nextId = snowflakeId + 1n;
Cryptography
// Large prime numbers
const prime = 104729n;
const modulo = 2n ** 256n - 1n;
// Modular exponentiation
function modPow(base, exponent, mod) {
let result = 1n;
base = base % mod;
while (exponent > 0n) {
if (exponent % 2n === 1n) {
result = (result * base) % mod;
}
exponent = exponent / 2n;
base = (base * base) % mod;
}
return result;
}
Financial Calculations
// Store amounts in cents/smallest unit as BigInt
class Money {
constructor(cents) {
this.cents = BigInt(cents);
}
add(other) {
return new Money(this.cents + other.cents);
}
multiply(factor) {
return new Money(this.cents * BigInt(factor));
}
toString() {
const str = this.cents.toString().padStart(3, '0');
return `$${str.slice(0, -2)}.${str.slice(-2)}`;
}
}
const price = new Money(9999); // $99.99
const quantity = 1000000;
const total = price.multiply(quantity);
console.log(total.toString()); // Precise calculation
High-Precision Timestamps
// Nanosecond timestamps
const timestampNs = 1234567890123456789n;
// Convert to components
const seconds = timestampNs / 1000000000n;
const nanos = timestampNs % 1000000000n;
Best Practices
- •Use String for Large Literals: When creating BigInt from large values, use strings to avoid precision loss
- •Be Explicit About Conversions: Always explicitly convert between Number and BigInt
- •Handle JSON Serialization: Implement custom serialization for BigInt values
- •Consider Performance: BigInt operations are slower than Number operations
- •Use for Integer-Only Operations: BigInt doesn't support decimals
Browser/Node.js Support
BigInt is supported in:
- •Chrome 67+
- •Firefox 68+
- •Safari 14+
- •Node.js 10.4+
Summary
| Feature | Description |
| ---------- | ------------------------------------------ | ----------------------- |
| Creation | 123n or BigInt(123) |
| Arithmetic | +, -, *, / (truncated), %, ** |
| Comparison | <, >, <=, >=, ==, === |
| Bitwise | &, |, ^, ~, <<, >> |
| No mixing | Cannot mix with Number in operations |
| No Math | Math object methods don't work with BigInt |
| JSON | Requires custom serialization |