W3docs

How to Format Numbers in Java

Format Java numbers using String.format, printf, DecimalFormat, and NumberFormat.

How to Format Numbers in Java

Java gives you several ways to turn a raw int, double, or BigDecimal into a human-friendly string: thousands separators, fixed decimal places, currency symbols, and percentages. This chapter walks through the four tools you reach for most: String.format/printf, DecimalFormat, and the locale-aware NumberFormat.

Quick Formatting with String.format and printf

For one-off formatting inside a log line or System.out, the format-string approach is the shortest path. printf prints directly; String.format returns the string so you can store it.

double price = 1234.5;
System.out.printf("%.2f%n", price);        // 1234.50
String s = String.format("%,.2f", price);  // 1,234.50
System.out.println(String.format("%08.2f", 42.5)); // 00042.50

The conversion %.2f fixes two decimal places, the comma flag , adds grouping separators, and %08.2f zero-pads the whole field to width 8. Use %n rather than \n for a platform-correct line break. The grouping separator follows the default locale, so the same code may print 1.234,50 on a German machine.

Custom Patterns with DecimalFormat

When you need full control over the pattern, or want to format many values with one reusable object, use DecimalFormat. You describe the output with a pattern of # (optional digit) and 0 (required digit) characters.

DecimalFormat df = new DecimalFormat("#,##0.00");
df.format(1234.5);   // "1,234.50"
df.format(0.5);      // "0.50"

DecimalFormat sci = new DecimalFormat("0.###E0");
sci.format(123456);  // "1.235E5"

DecimalFormat rounds with RoundingMode.HALF_EVEN by default, which can surprise you (2.5 rounds to 2). Set df.setRoundingMode(RoundingMode.HALF_UP) if you need the everyday "round half up" behaviour. A single DecimalFormat instance is not thread-safe, so create one per thread or guard it.

Locale-Aware Currency and Percent

For currency and percentages, do not build the pattern by hand. NumberFormat factory methods pick the right symbol, separators, and digit count for a Locale.

NumberFormat us = NumberFormat.getCurrencyInstance(Locale.US);
us.format(1234.5);   // "$1,234.50"

NumberFormat pct = NumberFormat.getPercentInstance(Locale.US);
pct.format(0.87);    // "87%"

Note that the percent formatter multiplies by 100, so you pass 0.87 to get 87%. Passing the right Locale is what makes the output correct for each market.

ApproachBest forLocale-awareReusable
printf / String.formatone-off outputyes (default locale)no
DecimalFormatcustom patterns, bulkyes (configurable)yes (not thread-safe)
NumberFormat.getCurrencyInstancemoneyyesyes
NumberFormat.getPercentInstanceratiosyesyes

A Complete, Runnable Example

The program below formats the same number four different ways, then shows zero-padding, so you can compare the outputs side by side.

java— editable, runs on the server

What to take from the run:

  • printf with %,.2f prints 1,234,567.89, adding grouping separators and fixing two decimals.
  • DecimalFormat("#,##0.00") produces the same 1,234,567.89 but as a reusable, returnable string.
  • getCurrencyInstance(Locale.US) prepends the $ symbol to give $1,234,567.89.
  • getPercentInstance multiplies 0.8736 by 100 and rounds it to 87%.
  • %08.2f zero-pads 42.5 to width 8, printing 00042.50.

Practice

Practice

Which call formats the double 0.87 as the string '87%'?