← 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.