Go Down

Topic: BUG: when (double) 2+2 does not equal four (Read 2137 times) previous topic - next topic


I've been playing with calculating sunrise/sunset on an arduino Diecimila.  Consider the following code fragment and the comments:

Code: [Select]
// debugging the J calculation
 double J1 = 2451545;  // ok - got 2451545
 double J2 = 0.0009;   // ok - got 0.0009
 double J3 = 2*M_PI;   // ok - got 6.283185
 double J4 = Lw/J3;    // ok - got 0.215978
 double J5 = J1 + J2;  // wrong - got 2451545.000000
 double J6 = J5 + J4;  // wrong - got 2451545.250000 - even
                       // assuming the bug is in the serial
                       // library println() function, its
                       // still wrong.
 double J7 = J6 + n;   // ok - ignoring previous errors, this
                       // gives 2455513.250000 which is correct.

I might have thought that there was a problem with a cast somewhere, but the bug occurs well after we've established the type of each variable *and* verified correct results.  Interestingly, only addition appears to be affected.  All other operations appear fine.


Nov 14, 2010, 06:07 pm Last Edit: Nov 14, 2010, 06:15 pm by davekw7x Reason: 1
In avr-gcc, doubles are 32-bit floats.  They are good for about seven significant decimal digits.  This has nothing to do with the Serial print function or any other library functions.

I'll look at J5:

How is J5 going to be stored in the machine?

The actual value of J1 + J2 is equal to 2451545.0009, which would require eleven significant decimal digits.

The compiler generates code that stores the 32-bit binary floating point number that is the closest that it can get to 2451545.0009.  That turns out to be 2451545.0

Bottom line: Adding a small number to a large number can result in loss of significance.




ok.  Maybe the wording should be a little clearer in the reference manual or an example given for the kinds of problems that can crop up due to the 32 bit double.

I can reduce one constant by 2451545 in the calculations and still get a usable result so maybe that's a better approach.  I'll give that a try.

Andy Brown

As well as the significant digits issue be careful with doing any calculations that rely on the accuracy of the fractional part of a float (or double) because its internal representation as a binary fraction does not map exactly to the set of decimal fractions. Many common decimals are repeating binary fractions.
Home of the Nokia QVGA TFT LCD hacks: http://andybrown.me.uk

Go Up

Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

via Egeo 16
Torino, 10131