BigDecimal and money

I researched and discovered that when working with currencies, the best way to do calculations is with the BigDecimal class.

With this in mind, I am working on a code that converts various types of foreign currency into American currency and vice versa (in particular, a cash register that takes currency and converts it into US money, calculates the changes and returns this amount for the client in foreign currency) .

Today, many of the methods use double , and two of them are accepted in int as a parameter that will be used when calculating the US currency.

Question:

Since I want to use the BigDecimal class in my calculations, should I change all my methods that do calculations using doubles in BigDecimal?

+7
source share
2 answers

Yes, you must change all floats or doubles to take either ints, longs, or BigDecimals .

Floats and doubles are not accurate for financial calculations. It is a very good idea to use the Money template to process amounts and currencies (this is a special type of Quantity ). To maintain a list of funds, possibly in different currencies, what you do efficiently is MoneyBag , a Money collection that can then summarize all values ​​based on the target currency and CurrencyExchangeService (currency conversion rates should also be saved as BigDecimals ).

Rounding should be performed after each operation in accordance with the number of decimal places desired and the rounding algorithm. The number of decimal places is usually a Currency property (see, for example, ISO 4217 ); if another number is not required (for example, when calculating gasoline, for example).

You should definitely look at Fowler's examples; but I also created a very simple uni-currency Money for the exercise . It uses only dollars and rounds up to two decimal places; but it is still a good base for future extensions.

+4
source

Yes, BigDecimal is definitely the right way (floating point almost never). Also in JDBC.

But having said that, there is a problem with rounding. In some cases, the European software legally requires 6 decimal places. In general, you will want to go round 2 places at every step. If you have a quantity with two decimal places and a price, you will get 4 decimal places and must round. Therefore, to make the ugly BigDecimal interface even uglier, you will probably need some helper functions (multiplyRounded?).

+1
source

All Articles