Floor Division in JavaScript: Math.floor() and Math.trunc() — Which to Use
JavaScript has no // operator like Python. Instead, you achieve floor division with Math.floor(a / b) — but the distinction between floor and truncate matters more than beginners expect, especially with negative numbers. JavaScript's % operator also differs from Python's for negatives. Understanding these differences prevents hard-to-trace bugs in pagination, indexing, and algorithm problems.
Math.floor() vs / : The Key Difference
console.log(10 / 3); // 3.3333... — true division, always float
console.log(Math.floor(10 / 3)); // 3 — floor division, integer quotient
console.log(10 % 3); // 1 — remainder
// For positive numbers they always satisfy:
// Math.floor(a / b) * b + (a % b) === a
// 3 * 3 + 1 === 10 ✓
Math.floor() vs Math.trunc(): Critical Difference for Negatives
Math.floor() rounds toward negative infinity (always down). Math.trunc() rounds toward zero. For positive numbers they're identical — for negatives they diverge:
// Positive numbers — same result:
console.log(Math.floor(10 / 3)); // 3
console.log(Math.trunc(10 / 3)); // 3
// Negative numbers — DIFFERENT results:
console.log(Math.floor(-10 / 3)); // -4 (-3.33 floors toward -∞)
console.log(Math.trunc(-10 / 3)); // -3 (-3.33 truncates toward zero)
// Which matches Python's // ?
// Python: -10 // 3 = -4 → Math.floor() matches Python's behavior
The % Operator with Negatives: JS vs Python
JavaScript's % is a remainder operator (sign follows dividend). Python's % is a modulo operator (sign follows divisor). They differ for negatives:
// Positive: identical
console.log(10 % 3); // 1 (same in JS and Python)
// Negative dividend: DIFFERENT
console.log(-10 % 3); // -1 in JavaScript (sign follows -10)
// Python: -10 % 3 = 2 (sign follows 3)
// To get Python-style always-non-negative modulo in JavaScript:
function pyMod(a, b) {
return ((a % b) + b) % b;
}
console.log(pyMod(-10, 3)); // 2 — matches Python's -10 % 3
The Invariant: Quotient + Remainder Always Add Up
// (Math.floor(a / b)) * b + (a % b) === a (for a, b > 0)
const a = 26, b = 3;
const quotient = Math.floor(a / b); // 8
const remainder = a % b; // 2
console.log(quotient * b + remainder === a); // true (8*3 + 2 = 26)
Real-World Patterns
// 1. Convert seconds to minutes and seconds:
const totalSeconds = 137;
const minutes = Math.floor(totalSeconds / 60); // 2
const seconds = totalSeconds % 60; // 17
console.log(`${minutes}m ${seconds}s`); // "2m 17s"
// 2. Binary search midpoint (no overflow):
const left = 0, right = 100;
const mid = Math.floor((left + right) / 2); // 50
// 3. Total pages needed (ceiling division):
const totalItems = 95, perPage = 10;
const pages = Math.ceil(totalItems / perPage); // 10
console.log(`${pages} pages`);
// 4. Distribute items into rows:
const items = 29, perRow = 4;
const fullRows = Math.floor(items / perRow); // 7
const leftover = items % perRow; // 1
console.log(`${fullRows} full rows, ${leftover} left over`);
Key Takeaways
- JavaScript has no
//operator — useMath.floor(a / b)for floor division. Math.floor()rounds toward −∞;Math.trunc()rounds toward zero — they differ for negatives.- JS
%returns a negative result when the dividend is negative — unlike Python's%. - Use
((a % b) + b) % bto get Python-style always-non-negative modulo. - Common uses: time conversion, binary search midpoint, pagination, row distribution.
What to Learn Next
With floor division solid, explore the full set of JavaScript Math methods: Math.ceil() for ceiling division, Math.round() for nearest-integer rounding, and Math.abs() for absolute value. Then apply modulo to practical problems: checking even/odd (n % 2 === 0), circular array indexing (i % arr.length), and FizzBuzz — a classic interview exercise built on %.