← Back to All Calculators

JavaScript: Round to 2 Decimal Places

Master all JavaScript methods for rounding to 2 decimals

JavaScript Decimal Rounding Overview

Rounding to 2 decimal places is one of the most common operations in JavaScript, especially for currency, percentages, and UI display. However, JavaScript's floating-point arithmetic can lead to unexpected results if not handled correctly.

This guide covers all methods for rounding to 2 decimal places in JavaScript and TypeScript, including Math.round(), toFixed(), Intl.NumberFormat, and custom solutions with their pros and cons.

1. Math.round() with Multiplication

The most reliable method for rounding to 2 decimal places. Multiply by 100, round, then divide by 100.

Formula

Math.round(num * 100) / 100

Examples:

// Basic examples
const num1 = 12.345;
const rounded1 = Math.round(num1 * 100) / 100;
console.log(rounded1);  // 12.35

const num2 = 12.344;
const rounded2 = Math.round(num2 * 100) / 100;
console.log(rounded2);  // 12.34

const num3 = 0.1 + 0.2;  // 0.30000000000000004
const rounded3 = Math.round(num3 * 100) / 100;
console.log(rounded3);  // 0.3

// Negative numbers
const num4 = -12.345;
const rounded4 = Math.round(num4 * 100) / 100;
console.log(rounded4);  // -12.35

// Edge case: banker's rounding
const num5 = 2.555;
const rounded5 = Math.round(num5 * 100) / 100;
console.log(rounded5);  // 2.55 (may vary due to float precision!)

Reusable Function:

/**
 * Round number to 2 decimal places
 * @param {number} num - Number to round
 * @returns {number} Rounded number
 */
function roundTo2Decimals(num) {
  return Math.round(num * 100) / 100;
}

// Usage
console.log(roundTo2Decimals(12.345));   // 12.35
console.log(roundTo2Decimals(99.999));   // 100
console.log(roundTo2Decimals(0.555));    // 0.56

// TypeScript version
const roundTo2Decimals = (num: number): number => {
  return Math.round(num * 100) / 100;
};

✓ Pros

  • • Returns a number (not string)
  • • Fast performance
  • • Works with math operations
  • • Handles negatives correctly

✗ Cons

  • • May have float precision issues
  • • Doesn't format for display
  • • No trailing zeros (2.5 not 2.50)

2. toFixed() Method

The toFixed() method converts a number to a string with a specified number of decimal places.

Syntax

number.toFixed(2)

Examples:

// Basic usage
const num1 = 12.345;
console.log(num1.toFixed(2));        // "12.35" (string!)

const num2 = 12.3;
console.log(num2.toFixed(2));        // "12.30" (adds trailing zero)

const num3 = 0.1 + 0.2;
console.log(num3.toFixed(2));        // "0.30"

// Convert back to number
const num4 = 12.345;
const rounded = parseFloat(num4.toFixed(2));
console.log(rounded);                // 12.35 (number)

// Alternative: use unary plus
const rounded2 = +num4.toFixed(2);
console.log(rounded2);               // 12.35 (number)

// Inline usage
console.log((12.345).toFixed(2));    // "12.35"
console.log(+(12.345).toFixed(2));   // 12.35

⚠️ Important: toFixed() Returns a String!

The toFixed() method returns a STRING, not a number. This can cause issues in calculations:

const price = 12.345;
const rounded = price.toFixed(2);     // "12.35" (string)

// Problem: string concatenation instead of addition
console.log(rounded + 10);            // "12.3510" (wrong!)

// Solution: convert back to number
console.log(parseFloat(rounded) + 10); // 22.35 (correct)
console.log(+rounded + 10);            // 22.35 (correct)

✓ Pros

  • • Simple, one-line syntax
  • • Includes trailing zeros
  • • Good for display formatting
  • • Consistent rounding

✗ Cons

  • • Returns string, not number
  • • Needs conversion for math
  • • No locale formatting

3. Intl.NumberFormat - For Currency and Localization

The Intl.NumberFormat API provides powerful formatting with locale support, perfect for displaying currency.

Currency Formatting:

// USD Currency
const usdFormatter = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'USD',
  minimumFractionDigits: 2,
  maximumFractionDigits: 2
});

console.log(usdFormatter.format(12.345));   // "$12.35"
console.log(usdFormatter.format(1234.5));   // "$1,234.50"
console.log(usdFormatter.format(0.1 + 0.2)); // "$0.30"

// EUR Currency
const eurFormatter = new Intl.NumberFormat('de-DE', {
  style: 'currency',
  currency: 'EUR'
});

console.log(eurFormatter.format(12.345));   // "12,35 €"

// GBP Currency
const gbpFormatter = new Intl.NumberFormat('en-GB', {
  style: 'currency',
  currency: 'GBP'
});

console.log(gbpFormatter.format(12.345));   // "£12.35"

Decimal Formatting (No Currency Symbol):

// Decimal formatting
const decimalFormatter = new Intl.NumberFormat('en-US', {
  minimumFractionDigits: 2,
  maximumFractionDigits: 2
});

console.log(decimalFormatter.format(12.345));   // "12.35"
console.log(decimalFormatter.format(12.3));     // "12.30"
console.log(decimalFormatter.format(1234.5));   // "1,234.50"

// Without thousand separators
const simpleFormatter = new Intl.NumberFormat('en-US', {
  minimumFractionDigits: 2,
  maximumFractionDigits: 2,
  useGrouping: false
});

console.log(simpleFormatter.format(1234.5));    // "1234.50"

Reusable Formatters:

// Create reusable formatter instance
const currencyFormatter = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'USD'
});

// Use multiple times (efficient)
const prices = [12.345, 23.456, 45.678];
prices.forEach(price => {
  console.log(currencyFormatter.format(price));
});
// Output:
// $12.35
// $23.46
// $45.68

// Percentage formatting
const percentFormatter = new Intl.NumberFormat('en-US', {
  style: 'percent',
  minimumFractionDigits: 2,
  maximumFractionDigits: 2
});

console.log(percentFormatter.format(0.1234));  // "12.34%"

✓ Pros

  • • Locale-aware formatting
  • • Currency symbols and codes
  • • Thousand separators
  • • Standard, built-in API

✗ Cons

  • • Returns string only
  • • More verbose setup
  • • Display-only (not for math)

4. Custom Helper Functions

Flexible Decimal Rounding:

/**
 * Round to any number of decimal places
 * @param {number} num - Number to round
 * @param {number} decimals - Number of decimal places (default: 2)
 * @returns {number} Rounded number
 */
function roundToDecimals(num, decimals = 2) {
  const factor = Math.pow(10, decimals);
  return Math.round(num * factor) / factor;
}

// Examples
console.log(roundToDecimals(12.345));        // 12.35
console.log(roundToDecimals(12.345, 1));     // 12.3
console.log(roundToDecimals(12.345, 3));     // 12.345
console.log(roundToDecimals(12.345, 0));     // 12

Round and Format for Display:

/**
 * Round and format number as string with 2 decimals
 * @param {number} num - Number to format
 * @returns {string} Formatted string
 */
function formatTo2Decimals(num) {
  return (Math.round(num * 100) / 100).toFixed(2);
}

// Examples
console.log(formatTo2Decimals(12.3));        // "12.30"
console.log(formatTo2Decimals(12.345));      // "12.35"
console.log(formatTo2Decimals(0.1 + 0.2));   // "0.30"

Safe Currency Rounding:

/**
 * Round currency value safely
 * @param {number} amount - Amount to round
 * @returns {number} Rounded amount (cents precision)
 */
function roundCurrency(amount) {
  // Handle potential floating point issues
  return Math.round((amount + Number.EPSILON) * 100) / 100;
}

// Examples
console.log(roundCurrency(12.345));          // 12.35
console.log(roundCurrency(0.1 + 0.2));       // 0.3
console.log(roundCurrency(2.555));           // 2.56

Method Comparison

MethodReturn TypeBest ForExample
Math.round() * 100NumberCalculations12.35
toFixed(2)StringSimple display"12.35"
Intl.NumberFormatStringCurrency, i18n"$12.35"
Custom functionNumber/StringSpecific needs12.35

Real-World Use Cases

1. E-commerce: Price Display

// Product pricing component
function formatPrice(price) {
  const formatter = new Intl.NumberFormat('en-US', {
    style: 'currency',
    currency: 'USD'
  });
  return formatter.format(price);
}

// Cart total calculation
function calculateTotal(items) {
  const subtotal = items.reduce((sum, item) => {
    return sum + (item.price * item.quantity);
  }, 0);

  const tax = subtotal * 0.08;
  const total = subtotal + tax;

  // Round to 2 decimals for accurate total
  return Math.round(total * 100) / 100;
}

// Example usage
const cart = [
  { price: 12.99, quantity: 2 },
  { price: 7.50, quantity: 1 }
];

const total = calculateTotal(cart);
console.log(formatPrice(total));  // "$35.93"

2. Percentage Display

// Calculate and display percentage
function formatPercentage(value, total) {
  const percentage = (value / total) * 100;
  const rounded = Math.round(percentage * 100) / 100;
  return rounded.toFixed(2) + '%';
}

// Examples
console.log(formatPercentage(45, 200));    // "22.50%"
console.log(formatPercentage(1, 3));       // "33.33%"

// Progress bar
function getProgress(completed, total) {
  const percent = (completed / total) * 100;
  return Math.round(percent * 100) / 100;
}

console.log(getProgress(7, 10));           // 70

3. Financial Calculations

// Interest calculation
function calculateInterest(principal, rate, years) {
  const interest = principal * rate * years;
  return Math.round(interest * 100) / 100;
}

// Loan payment calculator
function calculateMonthlyPayment(principal, annualRate, years) {
  const monthlyRate = annualRate / 12;
  const numPayments = years * 12;

  const payment = principal *
    (monthlyRate * Math.pow(1 + monthlyRate, numPayments)) /
    (Math.pow(1 + monthlyRate, numPayments) - 1);

  return Math.round(payment * 100) / 100;
}

// Example
const payment = calculateMonthlyPayment(200000, 0.045, 30);
console.log(`Monthly payment: $${payment.toFixed(2)}`);
// "Monthly payment: $1013.37"

4. UI Display with React/TypeScript

// TypeScript utility
const formatCurrency = (amount: number): string => {
  return new Intl.NumberFormat('en-US', {
    style: 'currency',
    currency: 'USD'
  }).format(amount);
};

// React component
interface PriceProps {
  amount: number;
}

const Price: React.FC<PriceProps> = ({ amount }) => {
  const rounded = Math.round(amount * 100) / 100;
  return <span className="price">{formatCurrency(rounded)}</span>;
};

// Usage
<Price amount={12.345} />  // Displays: $12.35

Floating-Point Precision Issues

The Problem

JavaScript uses binary floating-point arithmetic, which can't represent some decimals exactly:

console.log(0.1 + 0.2);                    // 0.30000000000000004
console.log(0.1 + 0.2 === 0.3);            // false!
console.log((0.2 * 100) + (0.01 * 100));   // 21.000000000000004

Solutions

1. Round After Operations

const result = Math.round((0.1 + 0.2) * 100) / 100;
console.log(result);  // 0.3 (correct!)

2. Use Number.EPSILON for Comparisons

function areEqual(a, b) {
  return Math.abs(a - b) < Number.EPSILON;
}

console.log(areEqual(0.1 + 0.2, 0.3));  // true

3. Work in Cents for Money

// Store money as integer cents
const price1 = 1299;  // $12.99
const price2 = 750;   // $7.50
const total = price1 + price2;  // 2049 cents

// Convert to dollars for display
const dollars = total / 100;
console.log(`$${dollars.toFixed(2)}`);  // "$20.49"

Best Practices

✓

Use Math.round() for Calculations

When you need the result as a number for further calculations, use Math.round(num * 100) / 100.

✓

Use Intl.NumberFormat for Display

For displaying currency or localized numbers, use Intl.NumberFormat for proper formatting.

✓

Round at Display Time, Not Storage

Store full precision values and round only when displaying to users to avoid cumulative errors.

✓

Consider Integer Math for Money

For financial applications, work in cents (integers) to avoid floating-point precision issues entirely.