Magic Magic Java

lilstevey on 2007-02-20T12:03:44

I do like a lot of things about the java language, however occasionally it does things that I do consider counter intuitive. Consider the following line of code:

BigDecimal result = new BigDecimal(10).divide(new BigDecimal(3));

Given appropriatte imports, by looking at the code I would not be at all suprised to see any of the following values stored in result:

  • 4
  • 3
  • 3.33
  • 3.33334
  • 3.333333
I find the actual output slightly outside of my predicted pool of predicted behavour:

Exception in thread "main" java.lang.ArithmeticException : Non-terminating decimal expansion; no exact representable decimal result. The logic thing to me given the operation would be to use defaults ( preferably controllable ones ), not to produce occasional errors that can confuse hell out of a beginner.


at least it's documented

lachoy on 2007-02-20T13:46:33

to be fair, this behavior is in the Javadocs :-)

I'm ambivalent about implementing defaults. I think one of the reasons you use a BigDecimal over a float is that you want precision, like when manipulating money. Forcing you to then specify that precision (with a scale and rounding mode) isn't that far out of bounds.

But you're right that beginners might not be aware of these trade-offs. Maybe they're just grabbing numberic fields out of a database and they're automatically mapped to BigDecimals...

but still mis-sold?

lilstevey on 2007-03-08T00:50:11

it's taken a while for me to respond to your post, sorry. I can only assume my revision overtook all other things java in my mental priority list for a bit

You have a very good point, it is in the javadocs, and in regards to precision, obviously anyone would need several landfill sites worth of justification for opting for a float for a decimal for currency, and there's additional concerns where countries like Mauritania and Madagascar are concerned ( Or at least I suspect there may be, given wikipedias entry on iso 4217 ). Whislt I'm sure you need no guidence, for any casual reader of this post, the example "a money class" by Matt Foemmel and Martin Fowler in "Patterns of Enterprise Application Architecture" explore some interesting issues on dealing with monies.

However, I think my main objections to divide(BigDecimal) is that, to me at least, the method name and arguments imply simplicity ( if it was called divideResultingInRepresentableQuotient I'd have less of an axe to grind ), and that it should therefore should either round to a default, or alternativly, and possibly preferable from the awareness point of view, throw a checked exception.