Working with double floating point math

Greetings,
The "Getting started with Arduino" book says that double floating point numbers can be up to 1.7976931348623157 * 10^308. In other words, 17 significant digits! After many hours of working on this I can't get more than 8 significants digits, the same as regular float. I am doing something wrong, or are double floats not really supported? Here is the code including the printDouble routine found elsewhere on this forum.

#include <math.h>

double f1;
double f2;
double f3;

void setup(){
  Serial.begin(9600);
  f1 = 12345.0;
  f2 = 10.1;
  f3 = f1 * f2;

  printDouble( f1, 1);
  Serial.println("");
  printDouble( f2, 1);
  Serial.println("");
  printDouble( f3, 1);
  Serial.println("");
}

void loop(){
}


void printDouble( double val, byte precision){
  // prints val with number of decimal places determine by precision
  // precision is a number from 0 to 6 indicating the desired decimial places
  // example: printDouble( 3.1415, 2); // prints 3.14 (two decimal places)

  Serial.print (int(val));  //prints the int part
  if( precision > 0) {
    Serial.print("."); // print the decimal point
    unsigned long frac;
    unsigned long mult = 1;
    byte padding = precision -1;
    while(precision--)
       mult *=10;

    if(val >= 0)
      frac = (val - int(val)) * mult;
    else
      frac = (int(val)- val ) * mult;
    unsigned long frac1 = frac;
    while( frac1 /= 10 )
      padding--;
    while(  padding--)
      Serial.print("0");
    Serial.print(frac,DEC) ;
  }
}

The serial window shows:

12345.0
10.1
-6388.00000000...000000000001310725

Many thanks,
John

On the Arduino platform, the double data type is exactly the same as the float - both are 32 bit values. 8 bits are used for the decimal multiplier (the exponent) and that leaves 24 bits for the sign and value - only enough for up to 8 significant decimal digits.

Thanks for the prompt reply. Wish I had asked many hours ago.

Are you, or anyone for that matter, aware of an Arduino compatible floating point co-processor that will do 14+ significant digits. I took a cursory look at the documents for the device at Sparkfun, but didn't see any mention of double precision.

Thanks,
John

When I have needed very high precision calculations I use the 64 bit integer data type supported by the Arduino compiler. If your floating point values can fit within the range of [ch8722]9,223,372,036,854,775,808 to +9,223,372,036,854,775,807 then you can do something like this if you multiply your values by however many places needed to remove the decimal point.

void setup() 
{ 
  Serial.begin(9600); 
  Serial.println("long long test"); 
  int64_t bigValue1 = 123456789012345LL;  
  int64_t bigValue2 = 999999999999999LL;

  int64_t bigResult = bigValue1 + bigValue2;  
  
  long result = bigResult / 10000000L;  // get the most significant digits   
  Serial.print(result);                 // and print them to the serial port 
  
  bigResult = bigResult - (10000000LL * result); // get the least significant digits.
  result = bigResult;                      
  Serial.println(result);                             

} 


void loop() {
}

this test sketch adds 123456789012345 to 999999999999999 and prints: 1123456789012344

Greetings mem,

Thank you for the generosity of your prompt and informative reply (again). Using the int64_t will go a long way towards solving the problem at hand.

John