Win a copy of Mesos in Action this week in the Cloud/Virtualizaton forum!

# Losing precision on a number

Dylan Margoczi
Ranch Hand
Posts: 38
Hi guys, i got a simple problem of losing precision when trying to use a ratio against total number values.

first I'll get a ratio simply by dividing a number by a total value, then i will use that ratio to get the same percentage of another total.
So if I have 2 totals, say 100 and 200 and the number I want from my first total is 20. I will divide 20 by 100 to get my ratio, then times my second total by the ratio to get 40.

The problem lies in the method I got that uses this. all the numbers are double and I think the problem is that a double type isn't large enough to use for a ratio and loses precision.

For example if I use 465 and 930 as my totals and the number i want from my first total is 125. (if i do the same calculation) :
My ratio is 0.26881720430107525
and the amount I get from using this ratio against the second total is 249.99999999999997 when I should get 250.

I hope I have explained this well enough...
Is there a sure way to overcome this problem?

Ulf Dittmer
Rancher
Posts: 42967
73
Since you seem to be surprised by this, you should start by reading #20 in the JavaBeginnersFaq. Possible solutions include using Math.round in some way and using the BigDecimal class.

Peter van de Riet
Ranch Hand
Posts: 112
Another tip: if you are sure the solution is an integer number, then consider rewriting your code in order to do first the multiplication and dividing that by the second number:
First 125*930 = 116250 (use a int or long if nessecary)
116250 / 465 = 250

Dylan Margoczi
Ranch Hand
Posts: 38
thanks for the input guys.
the problem is it can be any number not just an integer.

I've had a look at the BigDecimal class but it doesn't seem to solve my problem but make it worse.
here is basically how I've done my code. It's not a practical example but shows my problem.

printout :
ratio = 0.00215053763440860215
new total = 0.99999999999999999975

the new total should be the same as the original total. ie 1.

I can see where I am going wrong I just don't know how to fix this?

Dylan Margoczi
Ranch Hand
Posts: 38
line 12 in the code bdNumber should be bdTotal.

Rob Spoor
Sheriff
Posts: 20532
54
You are trying to represent a rational number as a digital number. Like you can never fully represent other rational numbers like 1/3 as a digital number (0.33333333333333333333...) you can never fully represent 1/465 as a digital number.

If you need to keep the full accuracy there is little else left but use a proper fractional class like Apache Commons Lang's Fraction. In short:

Dylan Margoczi
Ranch Hand
Posts: 38
thanks. I'll give that a try.