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) ;
}
}
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.
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