135

I have a BigDecimal field amount which represents money, and I need to print its value in the browser in a format like $123.00, $15.50, $0.33.

How can I do that?

(The only simple solution which I see myself is getting floatValue from BigDecimal and then using NumberFormat to make two-digit precision for the fraction part).

blacktide
  • 10,654
  • 8
  • 33
  • 53
Roman
  • 64,384
  • 92
  • 238
  • 332

7 Answers7

165
public static String currencyFormat(BigDecimal n) {
    return NumberFormat.getCurrencyInstance().format(n);
}

It will use your JVM’s current default Locale to choose your currency symbol. Or you can specify a Locale.

NumberFormat.getInstance(Locale.US)

For more info, see NumberFormat class.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
Luca Molteni
  • 5,230
  • 5
  • 34
  • 42
94

To set thousand separator, say 123,456.78 you have to use DecimalFormat:

DecimalFormat df = new DecimalFormat("#,###.00");
System.out.println(df.format(new BigDecimal(123456.75)));
System.out.println(df.format(new BigDecimal(123456.00)));
System.out.println(df.format(new BigDecimal(123456123456.78)));

Here is the result:

123,456.75
123,456.00
123,456,123,456.78

Although I set #,###.00 mask, it successfully formats the longer values too. Note that the comma(,) separator in result depends on your locale. It may be just space( ) for Russian locale.

zb226
  • 9,586
  • 6
  • 49
  • 79
Jeff_Alieffson
  • 2,672
  • 29
  • 34
  • 27
    If you prefer zero to be displayed as 0.00 (instead of .00), use the pattern `"#,##0.00"` instead. – Jonik May 17 '16 at 13:37
44

Another way which could make sense for the given situation is

BigDecimal newBD = oldBD.setScale(2);

I just say this because in some cases when it comes to money going beyond 2 decimal places does not make sense. Taking this a step further, this could lead to

String displayString = oldBD.setScale(2).toPlainString();

but I merely wanted to highlight the setScale method (which can also take a second rounding mode argument to control how that last decimal place is handled. In some situations, Java forces you to specify this rounding method).

demongolem
  • 9,474
  • 36
  • 90
  • 105
  • I think java enforces it in all cases, but the point is that some number comply with the scale, like 1.55, some don't like 1.555 and need a hit on how to round the x.xx5 part. – user1708042 Nov 04 '21 at 10:49
21
 BigDecimal pi = new BigDecimal(3.14);
 BigDecimal pi4 = new BigDecimal(12.56);

 System.out.printf("%.2f",pi);

// prints 3.14

System.out.printf("%.0f",pi4);

// prints 13

Fluch
  • 323
  • 3
  • 8
14

Similar to answer by @Jeff_Alieffson, but not relying on default Locale:

Use DecimalFormatSymbols for explicit locale:

DecimalFormatSymbols decimalFormatSymbols  = DecimalFormatSymbols.getInstance(new Locale("ru", "RU"));

Or explicit separator symbols:

DecimalFormatSymbols decimalFormatSymbols = new DecimalFormatSymbols();
decimalFormatSymbols.setDecimalSeparator('.');
decimalFormatSymbols.setGroupingSeparator(' ');

Then:

new DecimalFormat("#,##0.00", decimalFormatSymbols).format(new BigDecimal("12345"));

Result:

12 345.00
volkovs
  • 1,153
  • 2
  • 11
  • 24
1
BigDecimal("19.0001").setScale(2, BigDecimal.RoundingMode.DOWN)
Dima
  • 8,586
  • 4
  • 28
  • 57
1

I know this question is very old, but I was making similar thing in my kotlin app recently. So here is an example if anyone needs it:

val dfs = DecimalFormatSymbols.getInstance(Locale.getDefault())
val bigD = BigDecimal("1e+30")
val formattedBigD = DecimalFormat("#,##0.#",dfs).format(bigD)

Result displaying $formattedBigD:

1,000,000,000,000,000,000,000,000,000,000
Nick Wilde
  • 165
  • 3
  • 15