Maintaining precision
There are a few ways of maintaining precision. The first is to completely avoid fixed-precision floating-point binary number types like float
s and double
s if your currency uses decimal digits past the point. Here are a few good alternatives:
BigDecimal
java.math.BigDecimal
allows you to store precise finitely-long decimal values with ease, but it can be a bit slow.
Use BigDecimal
s if you need the programming to be easy and the results to be precise, but you're OK with slowness.
long
long
can be used to store the amount in cents rather than dollars if you're using US currency.
For other currencies, you can take the reciprocal of the rational GCD of the currency denominations and multiply everything by that when you store it.
Confused? Here's an example of Wolfram|Alpha doing all the hard work of figuring out from the available US currency denominations ($1/100 through $100) that it should multiply US currency by 100. Make sure to use fractions rather than decimals with this.
Use long
s if you need a lot of speed and are OK with the drawback that monetary amounts greater than US$92,233,720,368,547,758.07 give completely incorrect results.
Besides being fast by themselves, long
s also use a lot less memory and never require garbage collection of themselves, so that's another small speedup for them.
BigInteger
long
s can be replaced with java.math.BigInteger
s to avoid any overflow problems.
Use this if you want something in between the speed and slowness of the other two with no reasonable chance of ever overflowing.