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.
Introduction
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
double
variables.  We may want to multiply it by a noninteger number, like 0.015, or divide it by any type of number, thus getting the noninteger 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 0.7999999999999999
:
1 System.out.println( new BigDecimal( 0.7 + 0.1, MathContext.DECIMAL64 ) );System.out.println( new BigDecimal( 0.7 + 0.1, MathContext.DECIMAL64 ) );
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.
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 ðŸ™‚