Go Down

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

#### signal7

##### Nov 14, 2010, 04:38 pm
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.

#### davekw7x

#1
##### Nov 14, 2010, 06:07 pmLast 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.

Regards,

Dave

#### signal7

#2
##### Nov 14, 2010, 07:40 pm
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.

#### foxbat

#3
##### Nov 16, 2010, 11:02 pm
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.

Go Up