posted 8 years ago

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.

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.

posted 8 years ago

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.

posted 8 years ago

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

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

Posts: 38

posted 8 years ago

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.

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?

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

posted 8 years ago

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:

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:

SCJP 1.4 - SCJP 6 - SCWCD 5 - OCEEJBD 6 - OCEJPAD 6

How To Ask Questions How To Answer Questions

It is sorta covered in the JavaRanch Style Guide. |