Handling Currency
Created at: 09.12.2012
Currency in Java
The usage of currency is a common requirement in web applications. Any mathematical operation on currencies should be accurate.
The data types float and double are not appropriate for accurate operations. That’s because of the way a computer represents such a value internally (IEE 754 binary floating point format).
Let’s look at an example. A float or double can’t represent the number 0.1 exactly. An Operation like
System.out.println(1.00 - 9 * 0.1);
Will return 0.09999…. instead of the expected value 0.1. If you have lots of operations with such numbers you might face some surprises later on. When you work with currency such problems might be severe. So, is there a reliable way to deal with currency in java?
Datatype BigDecimal (java.math.BigDecimal)
BigDecimal is designed for accurate operations with decimals. Sadly it’s none of the atomic data types in java. As a consequence, you need to use it like the wrapper classes Integer, Double and so on. But be aware of a common problem:
System.out.println(new BigDecimal(-0.28));
…prints -0.2800000000000000266453525910037569701671600341796875 which is kinda unexpected. I recommend you always use the string based constructor:
System.out.println(new BigDecimal("-0.28"));
… prints -0.28.
Currency with JSF and JPA
Luckily, JPA 2.0 has built in support for BigDecimal. It maps BigDecimal to the SQL datatype decimal(19,2).
In addition, you can use a currency converter to print such values in a JSF view.
<h:outputText value="#{invoice.amount}"> <f:convertNumber currencySymbol="EUR" type="currency" /> </h:outputText>
As a result, a formatted currency output depending on the provided currencySymbol is displayed. The example will print “-0,28 EUR”.