I need to do the Kalman filter with very small float Q value. Thus, I wonder how many floating points can Arduino DUE deal with?
I tried this code:
void setup() {
Serial.begin(250000);
float var1 = -2.0 / 3.0;
Serial.println(var1, 10); // 7 digits precision ?
double var2 = -2.0 / 3.0;
Serial.println(var2, 20); // 14+ digits precision ?
}
void loop() {
}
/************* Results ***************
-0.6666666865
-0.66666666666666660745
********************************************/
In Wikipedia the "Double-precision floating-point format" article describes how 64-bit floating point numbers consist of a sign bit, 11-bit exponent and 52-bit mantissa. This has a bit precision of 53, giving you 53*log(2) = 15.9 decimal digits after the decimal point.
An example they give, is that smallest number greater than one (in "sign | exponent | mantissa" format) as being: 0x3ff0 0000 0000 0001. This gives a value of 1.0000000000000002. Note that it's accurate to 15 decimal places and almost 16.
This can be tested on the Due using the simple program below:
// Test: set the double to the smallest number greater than 1
union
{
double d; // double
struct
{
uint64_t mantissa : 52; // 52 bit mantissa
uint64_t exponent : 11; // 11 bit exponent
uint64_t sign : 1; // 1 bit sign
} part;
} doubleFloat;
void setup()
{
Serial.begin(115200);
doubleFloat.part.mantissa = 0x1; // Load mantissa
doubleFloat.part.exponent = 0x3FF; // Load exponent
doubleFloat.part.sign = 0x0; // Load sign
Serial.print(F("Double: "));
Serial.println(doubleFloat.d, 16); // Should output: 1.0000000000000002
}
void loop() {}
The answer returned from the Due is 1.0000000000000002, therefore the SAM3X8E does support double precision to 15 decimal places.