Reputation: 1651
I was trying to retrieve a few values from a database and use them in a Groovy script in order to find and compare the differences.
An example is as below (when I was using float value in definition and in the database they are defined as Number and with precision 2), this is how the output looks
>
Typically by seeing the values I would expect both the differences to be 16, but it is not.
Any suggestions on what I would have missed ?
Upvotes: 1
Views: 400
Reputation: 96394
When numbers are stored in your database with a type of NUMBER(x,2)
or similar, that means you are getting an exact numeric value with 2 places after the decimal. By converting these into floats you are introducing error (a small and bounded error, but a noticeable one as you have found out), because there is not an exact representation for some of these numbers. Some numbers when converted to binary are infinitely repeating and have to get truncated somewhere. BigDecimal represents the numbers exactly, as long as you don't construct them by passing in a floating point value, in which case the damage is already done before BigDecimal gets involved (all it can do at that point is exactly represent the floating point approximation of the original number). I think using BigDecimal is the easy solution to your problem.
Since it's a Groovy script I assume performance is not your biggest consideration, if it is (and you're concerned about all the garbage created by instantiating BigDecimals) then you might consider the delta approach suggested by JB Nizet. (See this article by Peter Lawrey for some pointers on how to work with floating point numbers.) But Java's GC expects a lot of ephemeral objects, it's usually not the biggest performance problem.
There's a question about floats vs decimals here with answers that describe why floating-point is not exact.
Upvotes: 1