You want to store your currency in
long and calculate your currency in
double, at least as a backup. You want all transactions to take place as
The reason you want to store your currency in
long is that you don't want to lose any currency.
Let's suppose you use a
double, and you have no money. Someone gives you three dimes, and then takes them back.
You: 0.1+0.1+0.1-0.1-0.1-0.1 = 2.7755575615628914E-17
Well, that's not so cool. Maybe someone with $10 wants to give their fortune away by first giving you three dimes, and then giving $9.70 to someone else.
Them: 10.0-0.1-0.1-0.1-9.7 = 1.7763568394002505E-15
And then you give them the dimes back:
Them: ...+0.1+0.1+0.1 = 0.3000000000000018
This is just broken.
Now, let's use a long, and we'll keep track of tenths of cents (so 1 = $0.001). Let's give everyone on the planet one billion, one hundred and twelve million, seventy five thousand, one hundred and forty three dollars:
Us: 7000000000L*1112075143000L = 1 894 569 218 048
Um, wait, we can give everyone over a billion dollars, and only spend a little over two? Overflow is a disaster here.
So, whenever you're calculating an amount of money to transfer, use
Math.round it to get a
long. Then fix up balances (add and subtract both accounts) using
Your economy won't leak, and it will scale up to a quadrillion dollars.
There are more tricky issues--for example, what do you do if you make twenty payments?*--but this should get you started.
* You calculate what one payment is, round to
long; then multiply by
20.0 and check that it's in range; if so, you multiply the payment by
20L to get the amount deducted from your balance. In general, all transactions must be handled as
long, so you really need to sum up all the individual transactions; you can multiply as a shortcut, but you need to make sure you don't add rounding errors and that you don't overflow, which means you need to check with
double before doing the real calculation with
Currencytype like Delphi's, which uses scaled fixed-point math to give you decimal math without the precision problems inherent to floating-point? \$\endgroup\$
BigDecimalfor these kind of problems. \$\endgroup\$