File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
The moose likes Java in General and the fly likes Losing precision on a number Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Java in General
Bookmark "Losing precision on a number" Watch "Losing precision on a number" New topic

Losing precision on a number

Dylan Margoczi
Ranch Hand

Joined: Jul 12, 2007
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?

thanks in advance.
Ulf Dittmer

Joined: Mar 22, 2005
Posts: 42965
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

Joined: Apr 09, 2004
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

Each number system has exactly 10 different digits.
Dylan Margoczi
Ranch Hand

Joined: Jul 12, 2007
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

Joined: Jul 12, 2007
Posts: 38
line 12 in the code bdNumber should be bdTotal.
Rob Spoor

Joined: Oct 27, 2005
Posts: 20274

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:

How To Ask Questions How To Answer Questions
Dylan Margoczi
Ranch Hand

Joined: Jul 12, 2007
Posts: 38
thanks. I'll give that a try.
I agree. Here's the link:
subject: Losing precision on a number
It's not a secret anymore!