Friday, April 23, 2010

BigDecimal v Float/float or Double/double for java transport

As I have posted previously, quite often I get involved in some type of financial portion of a solution, or the entirety of the solution is financial.

In java, BigDecimal is where you go for computational accuracy -- but what about if you just need to transport the data?

So, I reviewed information in the Sun/Oracle JDK site, and if you go search and read it, it isn't overly definitive (from a 'do I want to or not use') on float/doubles.

After going through many other posts, mailing list searches, and reviews, I broke down and posted a question here:

I also started doing some manual tests myself, and finally got the 'answer' I was looking for:

float: 9 'locations'
double: 15 'locations'

What are locations? My testing, I found that float can accurately store and retrieve 6 numbers before the decimal, and 3 after....or 3 before/6 after, or any variation of that theme. Similar for double - 9 before/6 after, and other variations.

Needless to say, that's why it is vague as it matters what scale you are storing after the decimal as to how much you can store before the decimal.

So, unless you can get a definitive max value and precision rule for a financial application, you might want to stick with the heavyweight of BigDecimal just to be sure.


Edit: I forgot to post *why* I was even looking at this!!

We were having some memory issues with an outsourced application (that lacked pagination), that had a DTO with 12 monetary value field...12 BigDecimals per DTO. The List sizes ranged from 300->2000->40k. The 40k (most extreme) was taking up 45MB of memory! Changing the BigDecimal to float primitive for the 12 fields dropped the same List size down to 15MB (1/3!!!!!).

However, the accuracy needed for this application was not satisfied by float, so although I'm evaluating Double I may opt to play it safe and keep accuracy as more important than saving memory (and, instead, actually paginate the results!).