How to calculate monetary values in Java – double vs BigDecimal
Monetary values usually program in financial application. When we deal with “money”, it’s always come to a question , should i use double or float variable to represent the monetary values in Java?
Here is an example to use double to represent the monetary values in Java
import java.math.BigDecimal; public class PrintChangeAmount { public static void main(String[] argv) { System.out.println("--- Normal Print-----"); System.out.println(2.00 - 1.1); System.out.println(2.00 - 1.2); System.out.println(2.00 - 1.3); System.out.println(2.00 - 1.4); System.out.println(2.00 - 1.5); System.out.println(2.00 - 1.6); System.out.println(2.00 - 1.7); System.out.println(2.00 - 1.8); System.out.println(2.00 - 1.9); System.out.println(2.00 - 2); } }
Output
--- Normal Print----- 0.8999999999999999 0.8 0.7 0.6000000000000001 0.5 0.3999999999999999 0.30000000000000004 0.19999999999999996 0.10000000000000009 0.0
Output is not what we expected. Generally, Java cannot calculate all double decimals precisely. This is the internal design of Java. So to avoid this kind of problem, we always use BigDecimal in monetary values calculation to avoid any precision loss.
Here is an example to use BigDecimal to represent the monetary values in Java
import java.math.BigDecimal; public class PrintChangeAmount { public static void main(String[] argv) { System.out.println("--- BigDecimal-----"); System.out.println(new BigDecimal("2.00").subtract(new BigDecimal("1.1"))); System.out.println(new BigDecimal("2.00").subtract(new BigDecimal("1.2"))); System.out.println(new BigDecimal("2.00").subtract(new BigDecimal("1.3"))); System.out.println(new BigDecimal("2.00").subtract(new BigDecimal("1.4"))); System.out.println(new BigDecimal("2.00").subtract(new BigDecimal("1.5"))); System.out.println(new BigDecimal("2.00").subtract(new BigDecimal("1.6"))); System.out.println(new BigDecimal("2.00").subtract(new BigDecimal("1.7"))); System.out.println(new BigDecimal("2.00").subtract(new BigDecimal("1.8"))); System.out.println(new BigDecimal("2.00").subtract(new BigDecimal("1.9"))); System.out.println(new BigDecimal("2.00").subtract(new BigDecimal("2"))); } }
Output
--- BigDecimal----- 0.90 0.80 0.70 0.60 0.50 0.40 0.30 0.20 0.10 0.00
BigDecimal performs exact decimal arithmetic. The output is what we expected.
Conclusion
BigDecimal should be used rather than doubles, especially for monetary calculations in Java. However BigDecimal calculations are slower than those with primitive data type calculations, which may be an issue for some heavy use of decimal calculations program, but there’s should be no consequence for most programs.
Caution!
Always use the BigDecimal(“String”) constructor, and never BigDecimal(double) for monetary calculation, please visit document below.
http://java.sun.com/javase/6/docs/api/java/math/BigDecimal.html#BigDecimal(double)
- Java Core Technology - Java RegEx, Java XML, Java I/O, Java Misc
- J2EE Frameworks - Hibernate, Spring 2.5, Spring MVC, Struts 1.x, Struts 2.x
- Build Tools - Maven, Archiva
- Unit Test - jUnit, TestNG
- Client Scripts - jQuery