JavaScript Rounding: Math.floor(), ceil(), round() and trunc()
In JavaScript, use Math.floor() to round down, Math.ceil() to round up, and Math.round() to select the nearest integer. Rounding down a negative number moves away from zero. When Math.round() receives a value exactly halfway between two integers, it selects the larger integer.
Compare the direction of each operation
Math.floor(1.6); // 1 Math.ceil(1.4); // 2 Math.round(1.5); // 2 Math.floor(-1.4); // -2 Math.ceil(-1.4); // -1 Math.round(-1.5); // -1
floor returns the greatest integer no larger than the input; ceil returns the smallest integer no smaller than it. round chooses the closest integer, resolving ties toward positive infinity, so Math.round(-1.5) is -1 rather than -2. Compare the definitions of Math.floor(), Math.ceil() and Math.round().
| Input | floor | ceil | round | trunc |
|---|---|---|---|---|
| 1.4 | 1 | 2 | 1 | 1 |
| 1.5 | 1 | 2 | 2 | 1 |
| 1.6 | 1 | 2 | 2 | 1 |
| -1.4 | -2 | -1 | -1 | -1 |
| -1.5 | -2 | -1 | -1 | -1 |
| -1.6 | -2 | -1 | -2 | -1 |
Use Math.trunc() to remove the fractional part
Math.trunc() discards the fractional part and moves toward zero. It matches floor for positive inputs but differs for negative ones. If a requirement says "remove decimal places", decide whether it means truncation or rounding toward negative infinity.
Math.floor(-1.9); // -2 Math.trunc(-1.9); // -1
See Math.trunc() for its definition. Another edge case is Math.round(-0.5), which returns negative zero. A normal display may hide its sign; use Object.is(result, -0) if distinguishing it matters.
Round at a different decimal or integer position
Math.round(1.25 * 10) / 10; // 1.3: One decimal place Math.floor(1.256 * 100) / 100; // 1.25: Two decimal places Math.ceil(1.251 * 100) / 100; // 1.26: Two decimal places Math.round(1234567 / 1000) * 1000; // 1235000: Rounded to the nearest thousand
To keep d decimal places, multiply by 10 to the power of d, perform the integer operation, then divide by the same factor. To round to a larger integer unit such as a thousand, divide first, round, then multiply. State the number of digits to retain explicitly: "round at the second decimal place" can be interpreted differently by readers.
Separate floating-point arithmetic from display formatting
Math.round(1.005 * 100) / 100; // 1: Some decimal fractions are not stored exactly (1.2).toFixed(2); // "1.20" typeof (1.2).toFixed(2); // "string"
JavaScript Number values use binary floating-point representation, so some decimal fractions are stored approximately. A scaled value can land just below an expected midpoint and change the rounding result. Adding Number.EPSILON is not a universal solution across magnitudes, signs and decimal positions. Exact decimal requirements need a suitable integer-unit design with defined bounds or a decimal arithmetic tool that implements the required rounding rules.
toFixed() returns a string with the requested number of decimal places. Keep the string when trailing zeros matter; converting it to Number removes that display information. It still formats the underlying approximate Number and does not replace exact decimal arithmetic. The toFixed() reference explains its return type and precision limits.
Complete runnable comparison
Save this as rounding.html in UTF-8 and open it in a browser. Compare the first six lines with the table, then inspect the scaled rounding and floating-point examples.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Comparing floor, ceil, round and trunc</title>
<style>
body { margin: 24px; font: 16px/1.7 sans-serif; }
input, button, select { font: inherit; max-width: 100%; }
label { display: block; margin-top: 12px; }
#output { white-space: pre-wrap; overflow-wrap: anywhere; }
</style>
</head>
<body>
<p>Compare the results for positive and negative values.</p>
<pre id="output" aria-live="polite"></pre>
<script>
const values = [1.4, 1.5, 1.6, -1.4, -1.5, -1.6];
const lines = values.map(value =>
`${value}: floor ${Math.floor(value)} / ceil ${Math.ceil(value)} / round ${Math.round(value)} / trunc ${Math.trunc(value)}`
);
lines.push(`One decimal place: ${Math.round(1.25 * 10) / 10}`);
lines.push(`Nearest thousand: ${Math.round(1234567 / 1000) * 1000}`);
lines.push(`Floating-point example: ${Math.round(1.005 * 100) / 100}`);
lines.push(`Display format: ${(1.2).toFixed(2)} / Type: ${typeof (1.2).toFixed(2)}`);
document.getElementById("output").textContent = lines.join("\n");
</script>
</body>
</html>
The final lines include One decimal place: 1.3, Nearest thousand: 1235000 and Floating-point example: 1. For text input, apply Number() conversion and finite-value validation first. Rounding NaN or infinity does not turn invalid input into an ordinary integer.

