How to Round Numbers to 2 Decimal Places in JavaScript

Rounding numbers to two decimal places comes up constantly in JavaScript — calculating prices, displaying currency, handling user input, processing form data. JavaScript gives you several ways to do it, and each one behaves slightly differently depending on your use case.

This guide covers every method worth knowing, when to use each one, and the gotchas that trip up even experienced developers.

The Quick Answer: toFixed()

The fastest way to round a number to two decimal places is toFixed(2):

const price = 19.456789;
console.log(price.toFixed(2)); // "19.46"

toFixed() rounds to the specified number of decimal places and returns a string, not a number. That distinction matters — if you need to do math with the result, you have to convert it back to a number first.

const price = 19.456789;
const rounded = parseFloat(price.toFixed(2));
console.log(rounded);        // 19.46
console.log(typeof rounded); // "number"

Or use the unary + operator for a shorter conversion:

const rounded = +price.toFixed(2);
console.log(rounded); // 19.46

Using Math.round()

Math.round() rounds to the nearest integer. To round to two decimal places, multiply by 100, round, then divide by 100:

function roundTo2(num) {
  return Math.round(num * 100) / 100;
}

console.log(roundTo2(19.456));  // 19.46
console.log(roundTo2(19.454));  // 19.45
console.log(roundTo2(19.455));  // 19.46
console.log(roundTo2(1.005));   // 1   ← floating point issue

This approach returns an actual number rather than a string, which makes it more useful for further calculations.

Notice the last example — 1.005 rounds to 1 instead of 1.01. That is a floating-point precision issue inherent to how JavaScript (and most languages) handle decimal arithmetic. More on that shortly.

Using Math.round() with Number.EPSILON

To handle the floating-point precision problem cleanly, add Number.EPSILON before rounding:

function roundTo2(num) {
  return Math.round((num + Number.EPSILON) * 100) / 100;
}

console.log(roundTo2(1.005));   // 1.01  ← fixed
console.log(roundTo2(19.456));  // 19.46
console.log(roundTo2(1.255));   // 1.26

Number.EPSILON is an extremely small number — essentially the smallest difference JavaScript can represent between two values. Adding it before the multiplication nudges numbers that sit right on the boundary in the right direction.

This is the most reliable Math.round() approach for financial and precision-sensitive work.

Using toFixed() vs Math.round() — Which to Use?

Here is the practical difference:

const num = 1.005;

console.log(num.toFixed(2));                              // "1.00" ← string, may be inaccurate
console.log(Math.round(num * 100) / 100);                 // 1     ← number, inaccurate
console.log(Math.round((num + Number.EPSILON) * 100) / 100); // 1.01 ← number, accurate

Use toFixed(2) when you need a formatted string for display — showing a price on screen, building an output label, formatting a value in a template literal. Remember to handle the string-to-number conversion if you need to do math with it.

Use Math.round() with Number.EPSILON when you need an actual number for further calculations, or when floating-point precision matters.

Formatting as Currency

For displaying money specifically, Intl.NumberFormat is the most robust option because it handles locale-specific formatting, currency symbols, and decimal separators automatically:

const price = 1234.5678;

const formatted = new Intl.NumberFormat("en-US", {
  style: "currency",
  currency: "USD",
}).format(price);

console.log(formatted); // "$1,234.57"

For different currencies and locales:

// British pounds
console.log(new Intl.NumberFormat("en-GB", {
  style: "currency",
  currency: "GBP",
}).format(1234.5678)); // "£1,234.57"

// Euros (Germany)
console.log(new Intl.NumberFormat("de-DE", {
  style: "currency",
  currency: "EUR",
}).format(1234.5678)); // "1.234,57 €"

Intl.NumberFormat is the right tool when the output is going to a user interface. It rounds correctly, adds the currency symbol, and formats thousands separators according to locale — all in one call.

A Reusable Rounding Utility

Here is a general-purpose rounding function that works for any number of decimal places:

function roundToDecimals(num, decimals = 2) {
  const factor = Math.pow(10, decimals);
  return Math.round((num + Number.EPSILON) * factor) / factor;
}

console.log(roundToDecimals(19.4567));    // 19.46  (default 2 decimals)
console.log(roundToDecimals(19.4567, 1)); // 19.5
console.log(roundToDecimals(19.4567, 3)); // 19.457
console.log(roundToDecimals(1.005));      // 1.01

Pass in the number and the number of decimal places you want. The default is 2. Math.pow(10, decimals) generates the right multiplier dynamically — 100 for two decimals, 1000 for three, and so on.

Rounding in an Array

When you need to round a list of numbers — API response values, form inputs, a dataset — map over the array:

const prices = [10.456, 22.789, 5.001, 99.999];

const rounded = prices.map(price =>
  Math.round((price + Number.EPSILON) * 100) / 100
);

console.log(rounded); // [10.46, 22.79, 5, 100]

Or use the reusable utility:

const rounded = prices.map(price => roundToDecimals(price));
console.log(rounded); // [10.46, 22.79, 5, 100]

The Floating-Point Problem Explained

This trips up a lot of developers and is worth understanding clearly.

console.log(0.1 + 0.2); // 0.30000000000000004

JavaScript uses 64-bit floating-point arithmetic (IEEE 754), the same standard used by most programming languages. Numbers like 0.1 and 0.2 cannot be represented exactly in binary, so tiny rounding errors accumulate during arithmetic.

This is why 1.005.toFixed(2) can return "1.00" instead of "1.01" — the actual stored value of 1.005 is something like 1.00499999999999989341..., which rounds down rather than up.

The Number.EPSILON fix works by adding just enough to push edge cases in the right direction. For most real-world rounding to two decimal places, it is the safest approach.

Complete Reference: All Methods at a Glance

const num = 19.4567;
const edgeCase = 1.005;

// toFixed() — returns string
console.log(num.toFixed(2));          // "19.46"
console.log(edgeCase.toFixed(2));     // "1.00" (may be inaccurate)

// Math.round() — returns number, may have edge case issues
console.log(Math.round(num * 100) / 100);          // 19.46
console.log(Math.round(edgeCase * 100) / 100);     // 1   (inaccurate)

// Math.round() with Number.EPSILON — most reliable
console.log(Math.round((num + Number.EPSILON) * 100) / 100);       // 19.46
console.log(Math.round((edgeCase + Number.EPSILON) * 100) / 100);  // 1.01

// Intl.NumberFormat — best for currency display
console.log(new Intl.NumberFormat("en-US", {
  style: "currency",
  currency: "USD"
}).format(num)); // "$19.46"

Tips for Rounding in JavaScript

Never use toFixed() for math. It returns a string. If you chain calculations on toFixed() output without converting back to a number first, JavaScript will concatenate strings instead of adding numbers.

Use Intl.NumberFormat for anything user-facing. It handles locale, currency symbols, and formatting correctly without extra logic.

Add Number.EPSILON when precision matters. Financial calculations, tax computation, and anything involving money should use the Number.EPSILON approach to avoid edge case rounding errors.

Round at the end, not the middle. If you are doing a series of calculations, round only the final result. Rounding intermediate values accumulates errors across steps.

Test your edge cases. 0.5, 1.005, 2.455, and similar values that sit exactly on the rounding boundary often behave unexpectedly with naive approaches. Test them before shipping…

Rounding to two decimal places in JavaScript means choosing between toFixed(2) for display strings and Math.round() with Number.EPSILON for reliable numeric results. Add Intl.NumberFormat when you need locale-aware currency formatting.

The floating-point quirks are real but entirely manageable once you understand why they happen and which approach protects against them. Use the Number.EPSILON pattern for anything precision-sensitive, test your edge cases, and round only the final result in any chain of calculations.

Leave a Comment