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.50The 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.
| Approach | Best for | Locale-aware | Reusable |
|---|---|---|---|
printf / String.format | one-off output | yes (default locale) | no |
DecimalFormat | custom patterns, bulk | yes (configurable) | yes (not thread-safe) |
NumberFormat.getCurrencyInstance | money | yes | yes |
NumberFormat.getPercentInstance | ratios | yes | yes |
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.
What to take from the run:
printfwith%,.2fprints1,234,567.89, adding grouping separators and fixing two decimals.DecimalFormat("#,##0.00")produces the same1,234,567.89but as a reusable, returnable string.getCurrencyInstance(Locale.US)prepends the$symbol to give$1,234,567.89.getPercentInstancemultiplies0.8736by 100 and rounds it to87%.%08.2fzero-pads42.5to width 8, printing00042.50.
Practice
Which call formats the double 0.87 as the string '87%'?