problem with multiplying two doubles

Started by
3 comments, last by jbadams 12 years, 2 months ago
hi,

I am desparete about one thing, this is what happens:

double d_cs=cos(0.00002); // the d_cs value by debugging is 0.99999999999800004
double sqr_dcs=d_cs*d_cs; // the sqr_dcs value by debugging is exactly 1.0000000000000000

As you can see, the sqr_dcs value should be something slightly smaller then d_cs but it is exactly one, and my following computations gets screwd (I get infinity values and such), plus I cannot allow myself such unpresicion. How come this?
Pls help
Advertisement
Floating point numbers are imprecise. They can only store a fixed number of significant digits. A double stores about 15 signifficant digits.

0.99999999999800004 is represented as: 9.99999999999800004e-1.

Squaring such value results in 9.999.... * 9.999... = 99.99999.... (accurately: 99.9999999999960000800000039998400016e-2)

d_cs is already at highest precision a double can store. But 99 has one more digit on the left, so one of digits on the right side falls off. And the result becomes 99.999999999999e-2. Since this particular value cannot be represented accurately, it's rounded according to certain rules, and it ends up as 1.0.

I cannot allow myself such unpresicion[/quote]

While there are mathematical methods that allow to compensate for these errors, they need to be applied to each step individually. Floating point is, by definition, imprecise. All such computations must be aware of that and compensate as needed. There is no simple solution. There will always be rounding errors, especially when combining large and small numbers.
You could try using library: http://gmplib.org

You could try using library: http://gmplib.org


No library offers complete and full precision, since some numbers cannot be represented (to our knowledge) in finite space.

For example: cos(Pi/4). While it's possible that arbitrary precision library provides sufficient accuracy, the problem doesn't go away. It's merely hidden by more powerful magic.

Aribtrary precision has also little use for graphics and simulation related problems. Graphics are painfully limited to floats and perhaps doubles. And simulations tend to be iterative, so errors, no matter how small, will accumulate unless compensated for.



There's another gotcha for doubles. Some CPUs use 80 bits of internal precision, but store values into memory as doubles (64 bits). So as long as numbers are in registers computations behave differently than when any of them needs to be stored to or loaded from memory.
Further reading: What Every Computer Scientist Should Know About Floating-Point Arithmetic.

- Jason Astle-Adams

This topic is closed to new replies.

Advertisement