I've researched and found that when dealing with currency, the best way to go about doing calculations is by the BigDecimal
class.
With that in mind, I'm working on a code that converts various types of foreign currency into US currency and vice-versa (specifically, a cashregister that takes foreign currency and converts it into US money, computes the change and returns this amount to the customer in foreign currency).
As of now, many of the methods use double
and two of them take in int
as a parameter to be used in computing the US currency.
Question:
Since I want to use the BigDecimal class in my calculations, should I change all my methods that make calculations involving doubles to a BigDecimal?
Yes, you should change all floats or doubles to take either ints, longs or BigDecimals
.
Floats and doubles are not precise for financial calculations. It's a very good idea to use the Money
pattern to deal with amounts and currencies (it's a special type of Quantity
). To maintain a list of moneys possibly in multiple currencies, what you're effectively doing is a MoneyBag
, a collection of Money
that can then sum all values given a target currency and a CurrencyExchangeService
(currency conversion rates should also be stored as BigDecimals
).
Rounding should be done after every operation according to the number of desired decimal places and the rounding algorithm. The number of decimal places is normally a property of the Currency
(look, e.g., at ISO 4217); unless a different number is desired (like when pricing gasoline, for example).
You should definitely look at Fowler's examples; but I've also created a very simple uni-currency Money
class for an exercise. It uses dollars only and rounds to 2 decimal places; but it's still a good base for future extensions.
Yes, BigDecimal is certainly the correct way (floating point almost never). Also in JDBC.
But having said that, there is an issue with rounding. In some cases 6 decimals are legally required in european software. In general you will want to round on 2 places in every step. If you have a quantity with 2 decimals and a price, you'll get 4 decimals, and have to round. So to make the ugly BigDecimal interface even uglier, you probably need some help functions (multiplyRounded?).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With