Docs

Module-08-Numbers-Math

14.1 Number Fundamentals

Overview

JavaScript has a single number type that handles both integers and floating-point numbers. Understanding how numbers work, their limitations, and the methods available for working with them is essential for writing reliable code.

Number System in JavaScript

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    JavaScript Number Type                        β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  Based on IEEE 754 double-precision 64-bit floating point       β”‚
β”‚                                                                  β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚  Sign    β”‚   Exponent    β”‚          Mantissa              β”‚  β”‚
β”‚  β”‚  1 bit   β”‚   11 bits     β”‚          52 bits               β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚                                                                  β”‚
β”‚  Safe Integer Range: -(2^53 - 1) to (2^53 - 1)                  β”‚
β”‚  Max Value: ~1.8 Γ— 10^308                                       β”‚
β”‚  Min Value: ~5 Γ— 10^-324                                        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Creating Numbers

// Number literals
let integer = 42;
let negative = -17;
let float = 3.14159;
let scientific = 2.998e8; // 299,800,000

// Special numeric literals
let binary = 0b1010; // 10 in binary
let octal = 0o755; // 493 in octal
let hex = 0xff; // 255 in hexadecimal

// Numeric separators (ES2021)
let billion = 1_000_000_000;
let bytes = 0xff_ff_ff_ff;

// Number constructor
let fromString = Number('42'); // 42
let fromBool = Number(true); // 1

Special Number Values

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    Special Number Values                         β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  Infinity        β”‚  Result of division by zero, overflow        β”‚
β”‚  -Infinity       β”‚  Negative infinity                           β”‚
β”‚  NaN             β”‚  "Not a Number" - invalid operation result   β”‚
β”‚  Number.MAX_VALUEβ”‚  Largest representable number                β”‚
β”‚  Number.MIN_VALUEβ”‚  Smallest positive number (closest to 0)     β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  NaN Behavior    β”‚  NaN !== NaN  (NaN is not equal to itself!)  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
// Infinity
console.log(1 / 0); // Infinity
console.log(-1 / 0); // -Infinity
console.log(Infinity + 1); // Infinity
console.log(Infinity - Infinity); // NaN

// NaN (Not a Number)
console.log(0 / 0); // NaN
console.log('hello' * 2); // NaN
console.log(Math.sqrt(-1)); // NaN

// NaN quirks
console.log(NaN === NaN); // false (!)
console.log(typeof NaN); // "number" (!)

Number Methods

Checking Methods

MethodDescriptionExample
Number.isNaN()Checks if value is NaNNumber.isNaN(NaN) β†’ true
Number.isFinite()Checks if value is finiteNumber.isFinite(42) β†’ true
Number.isInteger()Checks if value is integerNumber.isInteger(3.0) β†’ true
Number.isSafeInteger()Checks safe integer rangeNumber.isSafeInteger(2**53) β†’ false
// isNaN vs global isNaN
isNaN('hello'); // true (coerces to NaN first)
Number.isNaN('hello'); // false (no coercion)
Number.isNaN(NaN); // true

// isFinite
Number.isFinite(42); // true
Number.isFinite(Infinity); // false
Number.isFinite(NaN); // false

// isInteger
Number.isInteger(5); // true
Number.isInteger(5.0); // true
Number.isInteger(5.5); // false

// isSafeInteger
Number.isSafeInteger(42); // true
Number.isSafeInteger(2 ** 53); // false
Number.isSafeInteger(2 ** 53 - 1); // true

Conversion Methods

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                   Number Conversion Methods                      β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  toString(radix)   β”‚  Convert to string with optional base      β”‚
β”‚  toFixed(digits)   β”‚  Fixed decimal places                      β”‚
β”‚  toPrecision(sig)  β”‚  Total significant digits                  β”‚
β”‚  toExponential(d)  β”‚  Scientific notation                       β”‚
β”‚  valueOf()         β”‚  Primitive number value                    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
let num = 255;

// toString with different bases
num.toString(); // "255"
num.toString(2); // "11111111" (binary)
num.toString(8); // "377" (octal)
num.toString(16); // "ff" (hexadecimal)

// Decimal formatting
let pi = 3.14159265;
pi.toFixed(2); // "3.14"
pi.toFixed(4); // "3.1416" (rounded)
pi.toFixed(0); // "3"

// Precision
let big = 123456.789;
big.toPrecision(4); // "1.235e+5"
big.toPrecision(6); // "123457"
big.toPrecision(10); // "123456.7890"

// Scientific notation
let sci = 123456;
sci.toExponential(2); // "1.23e+5"
sci.toExponential(4); // "1.2346e+5"

Parsing Numbers

// parseInt - parses integers
parseInt('42'); // 42
parseInt('42.9'); // 42 (ignores decimal)
parseInt('42px'); // 42 (stops at non-digit)
parseInt('px42'); // NaN (must start with digit)
parseInt('0xFF'); // 255 (detects hex)
parseInt('1010', 2); // 10 (binary)
parseInt('ff', 16); // 255 (hexadecimal)

// parseFloat - parses floating-point
parseFloat('3.14'); // 3.14
parseFloat('3.14.15'); // 3.14 (stops at second dot)
parseFloat('  3.14  '); // 3.14 (trims whitespace)
parseFloat('3.14e2'); // 314

// Number() vs parseInt/parseFloat
Number('42px'); // NaN (strict)
parseInt('42px'); // 42 (lenient)

Number(''); // 0
parseInt(''); // NaN

Number(null); // 0
parseInt(null); // NaN

Number(true); // 1
parseInt(true); // NaN

Floating-Point Precision

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚              Floating-Point Precision Issues                    β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                  β”‚
β”‚   0.1 + 0.2 = 0.30000000000000004  (not 0.3!)                  β”‚
β”‚                                                                  β”‚
β”‚   Why? Binary can't exactly represent all decimal fractions    β”‚
β”‚   Just like 1/3 = 0.333... in decimal                          β”‚
β”‚                                                                  β”‚
β”‚   Solution: Use epsilon comparison or integer arithmetic        β”‚
β”‚                                                                  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
// The classic problem
console.log(0.1 + 0.2); // 0.30000000000000004
console.log(0.1 + 0.2 === 0.3); // false (!)

// Solution 1: Epsilon comparison
function almostEqual(a, b) {
  return Math.abs(a - b) < Number.EPSILON;
}
almostEqual(0.1 + 0.2, 0.3); // true

// Solution 2: Round to fixed decimals
function roundTo(num, decimals) {
  return Number(num.toFixed(decimals));
}
roundTo(0.1 + 0.2, 10); // 0.3

// Solution 3: Integer arithmetic (for currency)
// Work in cents instead of dollars
let priceInCents = 199 + 299; // 498 cents
let priceInDollars = priceInCents / 100; // $4.98

BigInt for Large Integers

// BigInt for integers beyond safe range
const big = 9007199254740991n; // BigInt literal
const alsoBig = BigInt('9007199254740991');

// Operations
big + 1n; // 9007199254740992n
big * 2n; // 18014398509481982n
big / 3n; // 3002399751580330n (truncates)

// Cannot mix BigInt and Number
// big + 1;              // TypeError!
big + BigInt(1); // Works

// Comparison works
big > 1000; // true
big === 9007199254740991n; // true

// Converting
Number(big); // 9007199254740991 (may lose precision)
String(big); // "9007199254740991"

Number Constants

ConstantValueDescription
Number.MAX_VALUE~1.8e308Largest representable number
Number.MIN_VALUE~5e-324Smallest positive number
Number.MAX_SAFE_INTEGER2^53 - 1Largest safe integer
Number.MIN_SAFE_INTEGER-(2^53 - 1)Smallest safe integer
Number.POSITIVE_INFINITYInfinityPositive infinity
Number.NEGATIVE_INFINITY-InfinityNegative infinity
Number.NaNNaNNot a Number
Number.EPSILON~2.2e-16Smallest difference between numbers

Common Patterns

// Clamp a number to a range
function clamp(num, min, max) {
  return Math.min(Math.max(num, min), max);
}
clamp(150, 0, 100); // 100
clamp(-50, 0, 100); // 0

// Check if a value is numeric
function isNumeric(value) {
  return !isNaN(parseFloat(value)) && isFinite(value);
}

// Format number with commas
function formatWithCommas(num) {
  return num.toLocaleString();
}
formatWithCommas(1234567); // "1,234,567"

// Currency formatting
function formatCurrency(amount, currency = 'USD') {
  return new Intl.NumberFormat('en-US', {
    style: 'currency',
    currency: currency,
  }).format(amount);
}
formatCurrency(1234.56); // "$1,234.56"

// Percentage formatting
function formatPercent(decimal) {
  return new Intl.NumberFormat('en-US', {
    style: 'percent',
    minimumFractionDigits: 1,
  }).format(decimal);
}
formatPercent(0.1234); // "12.3%"

Key Takeaways

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                      Number Fundamentals                         β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  1. JavaScript uses IEEE 754 double-precision floats            β”‚
β”‚  2. Special values: Infinity, -Infinity, NaN                    β”‚
β”‚  3. NaN !== NaN (use Number.isNaN() to check)                   β”‚
β”‚  4. Floating-point math can be imprecise (0.1 + 0.2)            β”‚
β”‚  5. Use BigInt for integers beyond safe integer range           β”‚
β”‚  6. Number.isNaN() is safer than global isNaN()                 β”‚
β”‚  7. parseInt/parseFloat are lenient; Number() is strict         β”‚
β”‚  8. Use Intl.NumberFormat for locale-aware formatting           β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
Module 08 Numbers Math - JavaScript Tutorial | DeepML