This article will discuss how to efficiently implement a Money class in Java. This article follows Using double/long vs BigDecimal for monetary calculations article published earlier in this blog.
As I have written before, we should not use any floating point types for storing monetary values. We should use
long instead, keeping the number of smallest currency units in it. Unfortunately, there is a couple of problems:
We may still have to communicate with a software storing monetary values in
- We may want to multiply it by a non-integer number, like 0.015, or divide it by any type of number, thus getting the non-integer result.
The easy way to deal with arithmetic operations is to use the
BigDecimal class for all of them. Unfortunately,
BigDecimal will not help you to deal with already incorrect
double calculations results. For example, the following code will print
So, we may say that
BigDecimal operations will produce the correct result if it had the correct arguments. We can not say the same about
double operations may end up with the exact result or a result which is one bit off the exact result. This is most likely caused by executing
double operations using higher precision on CPU and then rounding the result. All we need to do to get the exact result is to look at these 3 values (result; result plus one bit value, which is also known as ulp; and result minus ulp). One of them would be the correct one. Easy to say, difficult to efficiently implement 🙂