Exercise

BigInt is a built-in JavaScript type that can represent integers of arbitrary size, beyond the safe integer limit (Number.MAX_SAFE_INTEGER). Use it when working with very large integers such as database IDs, cryptographic values, or precise financial calculations.

javascript

const big = 9007199254740991n; // BigInt literal with 'n' suffix
console.log(big + 1n);         // 9007199254740992n (precise!)
console.log(typeof big);       // "bigint"

// Regular numbers lose precision here:
console.log(9007199254740991 + 2); // 9007199254740992 (wrong!)
console.log(9007199254740991n + 2n); // 9007199254740993n (correct)

Number.EPSILON is the smallest difference between two representable floating-point numbers (approximately 2.22e-16). It is used to compare floating-point numbers with a tolerance to avoid precision errors.

javascript

console.log(Number.EPSILON); // 2.220446049250313e-16

// Unsafe comparison:
console.log(0.1 + 0.2 === 0.3); // false

// Safe comparison using EPSILON:
function isEqual(a, b) {
    return Math.abs(a - b) < Number.EPSILON;
}
console.log(isEqual(0.1 + 0.2, 0.3)); // true

Safe integers are those that can be exactly represented in IEEE 754 double-precision format. The range is from Number.MIN_SAFE_INTEGER (-9007199254740991) to Number.MAX_SAFE_INTEGER (9007199254740991). Use Number.isSafeInteger() to check.

javascript

console.log(Number.MAX_SAFE_INTEGER); // 9007199254740991 (2^53 - 1)
console.log(Number.MIN_SAFE_INTEGER); // -9007199254740991

console.log(Number.isSafeInteger(42));                          // true
console.log(Number.isSafeInteger(Number.MAX_SAFE_INTEGER));     // true
console.log(Number.isSafeInteger(Number.MAX_SAFE_INTEGER + 1)); // false

JavaScript supports number literals in different bases using prefixes: 0b for binary (base 2), 0o for octal (base 8), and 0x for hexadecimal (base 16). They are evaluated as decimal at runtime.

javascript

console.log(0b1010);   // 10  (binary)
console.log(0o12);     // 10  (octal)
console.log(0xa);      // 10  (hexadecimal)

console.log(0xFF);     // 255
console.log(0b11111111); // 255
console.log(0o377);    // 255

Number.MAX_VALUE is the largest positive finite floating-point number (~1.8e+308). Any value larger than this overflows to Infinity. JavaScript uses 64-bit IEEE 754 representation.

javascript

console.log(Number.MAX_VALUE);           // 1.7976931348623157e+308
console.log(Number.MAX_VALUE * 2);       // Infinity

console.log(Number.MIN_VALUE);           // 5e-324 (smallest positive)
console.log(Number.POSITIVE_INFINITY);   // Infinity
console.log(Number.NEGATIVE_INFINITY);   // -Infinity

JavaScript supports scientific (exponential) notation using e or E to represent large or small numbers compactly. The number after e is the exponent (power of 10).

javascript

console.log(1e3);    // 1000
console.log(1.5e3);  // 1500
console.log(1e-3);   // 0.001
console.log(2.5e-4); // 0.00025

// JavaScript automatically uses this format for very large/small numbers:
console.log(0.000001);  // 0.000001
console.log(0.0000001); // 1e-7

Math.trunc() removes the fractional part of a number, always truncating toward zero. Math.floor() always rounds toward negative infinity, which is different for negative numbers.

javascript

console.log(Math.trunc(4.9));  // 4
console.log(Math.trunc(-4.9)); // -4 (toward zero)

console.log(Math.floor(4.9));  // 4
console.log(Math.floor(-4.9)); // -5 (toward -Infinity)

// trunc and floor agree for positive numbers, differ for negative

Math.random() returns a float in [0, 1). To get a random integer in [min, max], multiply and shift the result. Use Math.floor() to obtain a whole number.

javascript

// Random float [0, 1)
console.log(Math.random());

// Random integer [0, 9]
console.log(Math.floor(Math.random() * 10));

// Random integer [min, max] inclusive
function randomInt(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
}
console.log(randomInt(1, 6)); // simulates a die roll

Number.parseInt() is identical to the global parseInt() - it was added to Number in ES6 to reduce global namespace pollution and make the language more modular. Both parse a string and return an integer.

javascript

console.log(parseInt("42px"));         // 42
console.log(Number.parseInt("42px"));  // 42 (same result)

console.log(parseInt === Number.parseInt); // true (same function)

// Both accept a radix:
console.log(Number.parseInt("ff", 16)); // 255

Bitwise operators treat numbers as 32-bit signed integers and perform operations on their binary representations. They include AND (&), OR (|), XOR (^), NOT (~), left shift (<<), and right shift (>>).

javascript

console.log(5 & 3);   // 1  (0101 & 0011 = 0001)
console.log(5 | 3);   // 7  (0101 | 0011 = 0111)
console.log(5 ^ 3);   // 6  (0101 ^ 0011 = 0110)
console.log(~5);       // -6 (inverts all bits)
console.log(5 << 1);  // 10 (shift left = multiply by 2)
console.log(5 >> 1);  // 2  (shift right = divide by 2)