PDA

View Full Version : precision problem - Help pls



munna
15th May 2006, 13:55
Hi,

I am doing some calculations with double precision 8. Here is the problem:

First I calculate 1/6 which gives me 0.16666667 and then to this result I multiply 3 which gives me 0.50000001, but the ideal solution should be 0.5.

If I try the same thing with a calculator I get the ideal solution. How can I also get something like calculator - shoe maximum precision where ever needed and show least whereever not needed.

Thanks a lot.

vratojr
15th May 2006, 16:08
I don't know how you can do what you want...:) But I can give you some counsel concerning what I know...;) First of all, it is better to avoid useless calculation (like division and then multiplication) , you should do that by hand (if possibile) and use the final expression. Another thing would be particular numerical methos that can spare you some calculation (and the consequent error). For and "easy" introduction (but the methos showed can be out of date and not so theoretically "clean") to numerical methos you can take a look at Numerical Recipes http://www.nr.com/.
I hope it could help.

wysota
15th May 2006, 16:31
Not all values can be stored in floating point types and they get rounded to the nearest value (in this case 0.16666667).

1.0/6 = 0.16666667 (there is no way of storing 2/3 in a float or double)
0.16666667*3 = 0.(...)1 (because 7*3=21, so the result has to end with "1")

If you agree to loose one decimal place of the result, you can round the value and receive the proper result (0.5000000).

Another workaround is not to operate on floating point values as long as you can:

(1/6)*3 = 3*(1/6) = 3/6 = 0.5

munna
16th May 2006, 08:01
The example I gave was part of a big problem which the user gives. Therefore, I dont have much control over what user can enter. If give the same problem in windows calculator, it gives the answer perfectly i.e., 1/6 = 0.16666667 and then multiplying it with 3 gives 0.5.

Any idea on this ?

Thanks a lot.

jacek
16th May 2006, 13:27
Suppose that your number can have more than 8 digits after the decimal place.

This way you have:
> x = 1 / 6
x = 0.16666666...67
> x = 3 * x
x = 0.50000000...01

What would happen if you were displaying those numbers only up to 8th decimal place (of course rounded and without meaningless zeroes)?

bits
18th May 2006, 21:33
Another workaround is not to operate on floating point values as long as you can:

(1/6)*3 = 3*(1/6) = 3/6 = 0.5

Sticking with the above advise. I would like to maintain 2 floating variables.

float numerator = 1, denominator = 1;

Whenever you have to multiply fractions, keep multiplying numerators to the numerator, as well as keep multiplying denominators to the denominator.



//multiply (1/6)
numerator *= 1;
denominator *=6;

//multiply (3)
numerator *= 3;
denominator *=1; // since 3 can also be written as (3/1)

In the end calculate
result = numerator/denominator

iGoo
26th May 2006, 03:52
I try this code snippet in VC6

Then I got 0.5--The same as Windows small caculator.


int main(int argc, char* argv[])
{
double i;
/*
usr input stack of caculator.
*/
i = 1* 1.0 / 6;
i * =3 * 1.0 ;

return 0;
}

wysota
26th May 2006, 05:00
The compiler probably optimised that during compilation.