Pages: [1]   Go Down
Author Topic: BUG: when (double) 2+2 does not equal four  (Read 1145 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 5
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Code:
// 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.
Logged

Left Coast, USA
Offline Offline
Sr. Member
****
Karma: 7
Posts: 499
Sometimes I just can't help myself.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.



Regards,

Dave

« Last Edit: November 14, 2010, 12:15:54 pm by davekw7x » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 5
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Essex, UK
Offline Offline
Full Member
***
Karma: 4
Posts: 150
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Home of the Nokia QVGA TFT LCD hacks: http://andybrown.me.uk

Pages: [1]   Go Up
Jump to: