Teensy 3.0 and Arduino precision of double

Status
Not open for further replies.

WethaGuy

Member
I've searched the forum threads and the product pages but haven't found anything definitive on this simple question: what is the precision of the double type for the Teensy 3.0?

I'm working on a project that requires at least one more decimal place than the Arduino's double/float. I know the ARM chip can handle a "real" double but, does it implement it this way or does it follow Arduino's double-as-a-float implementation?
 
My Teensy3 experience is that the double type really is double precision. It is NOT like the original Arduino where double == float.
 
I
I'm working on a project that requires at least one more decimal place than the Arduino's double/float. I know the ARM chip can handle a "real" double but, does it implement it this way or does it follow Arduino's double-as-a-float implementation?
As JBeale says, double on the Teensy 3.0 is 64-bits. Note, the MK20DX128 32 bit ARM Cortex-M4 processor that is used in the Teensy 3.0 does not support hardware floating point (it would have to be a M4F to have floating point support), so all floating point is emulated.
 
testing "double" type on Teensy 3

In case it is helpful, here is a floating-point test program:

Code:
//
// Test of function that builds a C-style "string" for a floating point
// number in scientific notation.
//
// davekw7x
// December, 2010  // http://arduino.cc/forum/index.php/topic,46931.0.html
// modified to use "double" and to run to smaller / larger values  March 12 2013 JPB
//
void setup()
{
    double f;
    Serial.begin(115200);
    delay(3000);
    Serial.println("floating point test");

    f = 0.0;
    // No "digits" argument means 2 digits
    Serial.print("0.0 = ");Serial.println(float2s(f));Serial.println();
    
    // Rounding with leading zeros in the fractional part
    f = 10.3456;
    Serial.print(f,4);Serial.print(" = ");Serial.println(float2s(f, 4));Serial.println();
    
    /* 
       For loops 1 and 2, note that floating point
       overflows result values of"INF"
    */
    f = PI;
    Serial.println("Loop 1");
    for (int i=1; i< 58; i++)
    {
        Serial.println(float2s(f, 10));
        f *=1E6;
    }
    Serial.println();

    f = -PI;
    Serial.println("Loop 2");
    for (int i=1; i< 58; i++)
    {
        Serial.println(float2s(f, 10));
        f *=1E6;
    }  
    Serial.println();

    /*
       For loops 3 and 4 note that floating point
       underflows result in values that go to zero.
    */
    f = PI;
    Serial.println("Loop 3");
    for (int i=1; i< 60; i++)
    {
        Serial.println(float2s(f, 10));
        f /= 1E6;
    }
    Serial.println();

    f = -PI;
    Serial.println("Loop 4");
    for (int i=1; i< 58; i++)
    {
        Serial.println(float2s(f, 10));
        f /= 1E6;
    }
    Serial.println();

    /*
       Loop 5 shows rounding as follows:
        6: 1.999518 E+20
        5: 1.99952 E+20
        4: 1.9995 E+20
        3: 2.000 E+20
        2: 2.00 E+20
        1: 2.0 E+20
        0: 2 E+20
    */

    f = 1.999518e20;
    Serial.println("Loop 5");
    for (int i = 9; i >= 0; i--) {
        Serial.print(i);Serial.print(": ");Serial.println(float2s(f, i));
    }
    Serial.println();
    
    /* 
       Loop 6 shows rounding as follows:
        6: 1.999496 E+20
        5: 1.99950 E+20
        4: 1.9995 E+20
        3: 1.999 E+20
        2: 2.00 E+20
        1: 2.0 E+20
        0: 2 E+2
    */
    
    f = 1.999496e20;
    Serial.println("Loop 6");
    for (int i = 9; i >= 0; i--) {
        Serial.print(i);Serial.print(": ");Serial.println(float2s(f, i));
    }    
    Serial.println();
    
    Serial.println("NaN tests");
    f = sqrt(-1);
    Serial.print("sqrt(-1) = ");Serial.println(float2s(f, 3));

    f = 0.0/0.0;
    Serial.print("0.0/0.0 = ");Serial.println(float2s(f, 4));

    f = INFINITY * 0;
    Serial.print("INFINITY*0 = ");Serial.println(float2s(f, 5));Serial.println();

    
    Serial.println("INFINITY tests");
    f = 1.0/0;
    Serial.print("1.0/0 = ");Serial.println(float2s(f, 1));
    //printBytes(f); 

    f = -1.0/0;
    Serial.print("1.0/-0 = ");Serial.println(float2s(f, 1)); 
    //printBytes(f); 

    f = -1.0/0L;
    Serial.print("1.0/0L = ");Serial.println(float2s(f, 2));
    
    f = 1.0/0UL;
    Serial.print("1.0/0UL = ");Serial.println(float2s(f, 3));
    
    Serial.println();
    
    // Note that tan(pi/2) may not result in INF due
    // to limited precision.
    //
    f = tan(HALF_PI);
    Serial.print("tan(");Serial.print(HALF_PI, 6);Serial.print(") = ");  
    Serial.println(float2s(f, 6));
}

void loop()
{
} 

char * float2s(double f)
{
  return float2s(f, 2);
}

char * float2s(double f, unsigned int digits)
{
  int index = 0;
  static char s[16];                    // buffer to build string representation
  // handle sign
  if (f < 0.0)
  {
    s[index++] = '-';
    f = -f;
  } 
  // handle infinite values
  if (isinf(f))
  {
    strcpy(&s[index], "INF");
    return s;
  }
  // handle Not a Number
  if (isnan(f)) 
  {
    strcpy(&s[index], "NaN");
    return s;
  }

  // max digits
  if (digits > 9) digits = 9;
  long multiplier = pow(10, digits);     // fix int => long

  int exponent = int(log10(f));
  double g = f / pow(10, exponent);
  if ((g < 1.0) && (g != 0.0))      
  {
    g *= 10;
    exponent--;
  }
 
  long whole = long(g);                     // single digit
  long part = long((g-whole)*multiplier);   // # digits
  char format[16];
  sprintf(format, "%%ld.%%0%dld E%%+d", digits);
  sprintf(&s[index], format, whole, part, exponent);
  
  return s;
}

And here is the output on Teensy 3.0 (although I'm still running Paul's Arduino 1.0.2 beta 8)

Code:
floating point test
0.0 = 0.00 E-2147483648

10.3456 = 1.0345 E+1

Loop 1
3.141592653 E+0
3.141592653 E+6
3.141592653 E+12
3.141592653 E+18
3.141592653 E+24
3.141592653 E+30
3.141592653 E+36
3.141592653 E+42
3.141592653 E+48
3.141592653 E+54
3.141592653 E+60
3.141592653 E+66
3.141592653 E+72
3.141592653 E+78
3.141592653 E+84
3.141592653 E+90
3.141592653 E+96
3.141592653 E+102
3.141592653 E+108
3.141592653 E+114
3.141592653 E+120
3.141592653 E+126
3.141592653 E+132
3.141592653 E+138
3.141592653 E+144
3.141592653 E+150
3.141592653 E+156
3.141592653 E+162
3.141592653 E+168
3.141592653 E+174
3.141592653 E+180
3.141592653 E+186
3.141592653 E+192
3.141592653 E+198
3.141592653 E+204
3.141592653 E+210
3.141592653 E+216
3.141592653 E+222
3.141592653 E+228
3.141592653 E+234
3.141592653 E+240
3.141592653 E+246
3.141592653 E+252
3.141592653 E+258
3.141592653 E+264
3.141592653 E+270
3.141592653 E+276
3.141592653 E+282
3.141592653 E+288
3.141592653 E+294
3.141592653 E+300
3.141592653 E+306
INF
INF
INF
INF
INF

Loop 2
-3.141592653 E+0
-3.141592653 E+6
-3.141592653 E+12
-3.141592653 E+18
-3.141592653 E+24
-3.141592653 E+30
-3.141592653 E+36
-3.141592653 E+42
-3.141592653 E+48
-3.141592653 E+54
-3.141592653 E+60
-3.141592653 E+66
-3.141592653 E+72
-3.141592653 E+78
-3.141592653 E+84
-3.141592653 E+90
-3.141592653 E+96
-3.141592653 E+102
-3.141592653 E+108
-3.141592653 E+114
-3.141592653 E+120
-3.141592653 E+126
-3.141592653 E+132
-3.141592653 E+138
-3.141592653 E+144
-3.141592653 E+150
-3.141592653 E+156
-3.141592653 E+162
-3.141592653 E+168
-3.141592653 E+174
-3.141592653 E+180
-3.141592653 E+186
-3.141592653 E+192
-3.141592653 E+198
-3.141592653 E+204
-3.141592653 E+210
-3.141592653 E+216
-3.141592653 E+222
-3.141592653 E+228
-3.141592653 E+234
-3.141592653 E+240
-3.141592653 E+246
-3.141592653 E+252
-3.141592653 E+258
-3.141592653 E+264
-3.141592653 E+270
-3.141592653 E+276
-3.141592653 E+282
-3.141592653 E+288
-3.141592653 E+294
-3.141592653 E+300
-3.141592653 E+306
-INF
-INF
-INF
-INF
-INF

Loop 3
3.141592653 E+0
3.141592653 E-6
3.141592653 E-12
3.141592653 E-18
3.141592653 E-24
3.141592653 E-30
3.141592653 E-36
3.141592653 E-42
3.141592653 E-48
3.141592653 E-54
3.141592653 E-60
3.141592653 E-66
3.141592653 E-72
3.141592653 E-78
3.141592653 E-84
3.141592653 E-90
3.141592653 E-96
3.141592653 E-102
3.141592653 E-108
3.141592653 E-114
3.141592653 E-120
3.141592653 E-126
3.141592653 E-132
3.141592653 E-138
3.141592653 E-144
3.141592653 E-150
3.141592653 E-156
3.141592653 E-162
3.141592653 E-168
3.141592653 E-174
3.141592653 E-180
3.141592653 E-186
3.141592653 E-192
3.141592653 E-198
3.141592653 E-204
3.141592653 E-210
3.141592653 E-216
3.141592653 E-222
3.141592653 E-228
3.141592653 E-234
3.141592653 E-240
3.141592653 E-246
3.141592653 E-252
3.141592653 E-258
3.141592653 E-264
3.141592653 E-270
3.141592653 E-276
3.141592653 E-282
3.141592653 E-288
3.141592653 E-294
3.141592653 E-300
3.141592653 E-306
3.141592653 E-312
3.141589794 E-318
5.000000000 E-324
0.000000000 E-2147483648
0.000000000 E-2147483648
0.000000000 E-2147483648
0.000000000 E-2147483648

Loop 4
-3.141592653 E+0
-3.141592653 E-6
-3.141592653 E-12
-3.141592653 E-18
-3.141592653 E-24
-3.141592653 E-30
-3.141592653 E-36
-3.141592653 E-42
-3.141592653 E-48
-3.141592653 E-54
-3.141592653 E-60
-3.141592653 E-66
-3.141592653 E-72
-3.141592653 E-78
-3.141592653 E-84
-3.141592653 E-90
-3.141592653 E-96
-3.141592653 E-102
-3.141592653 E-108
-3.141592653 E-114
-3.141592653 E-120
-3.141592653 E-126
-3.141592653 E-132
-3.141592653 E-138
-3.141592653 E-144
-3.141592653 E-150
-3.141592653 E-156
-3.141592653 E-162
-3.141592653 E-168
-3.141592653 E-174
-3.141592653 E-180
-3.141592653 E-186
-3.141592653 E-192
-3.141592653 E-198
-3.141592653 E-204
-3.141592653 E-210
-3.141592653 E-216
-3.141592653 E-222
-3.141592653 E-228
-3.141592653 E-234
-3.141592653 E-240
-3.141592653 E-246
-3.141592653 E-252
-3.141592653 E-258
-3.141592653 E-264
-3.141592653 E-270
-3.141592653 E-276
-3.141592653 E-282
-3.141592653 E-288
-3.141592653 E-294
-3.141592653 E-300
-3.141592653 E-306
-3.141592653 E-312
-3.141589794 E-318
-5.000000000 E-324
0.000000000 E-2147483648
0.000000000 E-2147483648

Loop 5
9: 1.999517999 E+20
8: 1.99951799 E+20
7: 1.9995179 E+20
6: 1.999517 E+20
5: 1.99951 E+20
4: 1.9995 E+20
3: 1.999 E+20
2: 1.99 E+20
1: 1.9 E+20
0: 1.0 E+20

Loop 6
9: 1.999495999 E+20
8: 1.99949600 E+20
7: 1.9994960 E+20
6: 1.999495 E+20
5: 1.99949 E+20
4: 1.9994 E+20
3: 1.999 E+20
2: 1.99 E+20
1: 1.9 E+20
0: 1.0 E+20

NaN tests
sqrt(-1) = NaN
0.0/0.0 = NaN
INFINITY*0 = NaN

INFINITY tests
1.0/0 = INF
1.0/-0 = -INF
1.0/0L = -INF
1.0/0UL = INF

tan(1.570796) = 1.633123 E+16

And here is the output of the same code, running on Teensy 2.0:

Code:
floating point test
0.0 = 0.00 E+0

10.3456 = 1.0345 E+1

Loop 1
3.141592688 E+0
3.141593648 E+6
3.141594352 E+12
3.141595312 E+18
3.141596496 E+24
3.141605568 E+30
3.141598176 E+36
INF
INF
INF
INF
INF
INF
INF
INF
INF
INF
INF
INF
INF
INF
INF
INF
INF
INF
INF
INF
INF
INF
INF
INF
INF
INF
INF
INF
INF
INF
INF
INF
INF
INF
INF
INF
INF
INF
INF
INF
INF
INF
INF
INF
INF
INF
INF
INF
INF
INF

Loop 2
-3.141592688 E+0
-3.141593648 E+6
-3.141594352 E+12
-3.141595312 E+18
-3.141596496 E+24
-3.141605568 E+30
-3.141598176 E+36
-INF
-INF
-INF
-INF
-INF
-INF
-INF
-INF
-INF
-INF
-INF
-INF
-INF
-INF
-INF
-INF
-INF
-INF
-INF
-INF
-INF
-INF
-INF
-INF
-INF
-INF
-INF
-INF
-INF
-INF
-INF
-INF
-INF
-INF
-INF
-INF
-INF
-INF
-INF
-INF
-INF
-INF
-INF
-INF
-INF
-INF
-INF
-INF
-INF
-INF

Loop 3
3.141592688 E+0
3.141591728 E-6
3.141586960 E-12
3.141594112 E-18
3.141584816 E-24
3.141591968 E-30
3.141583152 E-36
3.141816080 E-42
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0

Loop 4
-3.141592688 E+0
-3.141591728 E-6
-3.141586960 E-12
-3.141594112 E-18
-3.141584816 E-24
-3.141591968 E-30
-3.141583152 E-36
-3.141816080 E-42
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0
0.000000000 E+0

Loop 5
9: 1.999519552 E+20
8: 1.99951960 E+20
7: 1.9995183 E+20
6: 1.999518 E+20
5: 1.99950 E+20
4: 1.9994 E+20
3: 1.998 E+20
2: 1.98 E+20
1: 1.9 E+20
0: 1.0 E+20

Loop 6
9: 1.999497536 E+20
8: 1.99949760 E+20
7: 1.9994963 E+20
6: 1.999496 E+20
5: 1.99948 E+20
4: 1.9993 E+20
3: 1.998 E+20
2: 1.98 E+20
1: 1.9 E+20
0: 1.0 E+20

NaN tests
sqrt(-1) = NaN
0.0/0.0 = NaN
INFINITY*0 = NaN

INFINITY tests
1.0/0 = INF
1.0/-0 = -INF
1.0/0L = -INF
1.0/0UL = INF

tan(1.570796) = -2.287736 E+7
 
Last edited:
In case it is helpful, here is a floating-point test program:

Using your example on a Teensy 3.0 with the latest teensyduino (1.12) gives the same results as on beta 8:
Code:
floating point test
0.0 = 0.00 E-2147483648

10.3456 = 1.0345 E+1

Loop 1
3.141592 E+0
3.141592 E+3
3.141592 E+6
3.141592 E+9
3.141592 E+12
3.141592 E+15
3.141592 E+18
3.141592 E+21
3.141592 E+24
3.141592 E+27
3.141592 E+30
3.141592 E+33
3.141592 E+36
3.141592 E+39
3.141592 E+42
3.141592 E+45
3.141592 E+48
3.141592 E+51
3.141592 E+54
3.141592 E+57
3.141592 E+60
3.141592 E+63
3.141592 E+66
3.141592 E+69
3.141592 E+72
3.141592 E+75
3.141592 E+78
3.141592 E+81
3.141592 E+84

Loop 2
-3.1415 E+0
-3.1415 E+3
-3.1415 E+6
-3.1415 E+9
-3.1415 E+12
-3.1415 E+15
-3.1415 E+18
-3.1415 E+21
-3.1415 E+24
-3.1415 E+27
-3.1415 E+30
-3.1415 E+33
-3.1415 E+36
-3.1415 E+39
-3.1415 E+42
-3.1415 E+45
-3.1415 E+48
-3.1415 E+51
-3.1415 E+54
-3.1415 E+57
-3.1415 E+60
-3.1415 E+63
-3.1415 E+66
-3.1415 E+69
-3.1415 E+72
-3.1415 E+75
-3.1415 E+78
-3.1415 E+81
-3.1415 E+84

Loop 3
3.1415 E+0
3.1415 E-3
3.1415 E-6
3.1415 E-9
3.1415 E-12
3.1415 E-15
3.1415 E-18
3.1415 E-21
3.1415 E-24
3.1415 E-27
3.1415 E-30
3.1415 E-33
3.1415 E-36
3.1415 E-39
3.1415 E-42
3.1415 E-45
3.1415 E-48
3.1415 E-51
3.1415 E-54
3.1415 E-57
3.1415 E-60
3.1415 E-63
3.1415 E-66
3.1415 E-69
3.1415 E-72
3.1415 E-75
3.1415 E-78
3.1415 E-81
3.1415 E-84
3.1415 E-87
3.1415 E-90
3.1415 E-93
3.1415 E-96
3.1415 E-99
3.1415 E-102
3.1415 E-105
3.1415 E-108
3.1415 E-111
3.1415 E-114

Loop 4
-3.1415 E+0
-3.1415 E-3
-3.1415 E-6
-3.1415 E-9
-3.1415 E-12
-3.1415 E-15
-3.1415 E-18
-3.1415 E-21
-3.1415 E-24
-3.1415 E-27
-3.1415 E-30
-3.1415 E-33
-3.1415 E-36
-3.1415 E-39
-3.1415 E-42
-3.1415 E-45
-3.1415 E-48
-3.1415 E-51
-3.1415 E-54
-3.1415 E-57
-3.1415 E-60
-3.1415 E-63
-3.1415 E-66
-3.1415 E-69
-3.1415 E-72
-3.1415 E-75
-3.1415 E-78
-3.1415 E-81
-3.1415 E-84
-3.1415 E-87
-3.1415 E-90
-3.1415 E-93
-3.1415 E-96
-3.1415 E-99
-3.1415 E-102
-3.1415 E-105
-3.1415 E-108
-3.1415 E-111
-3.1415 E-114

Loop 5
6: 1.999517 E+20
5: 1.99951 E+20
4: 1.9995 E+20
3: 1.999 E+20
2: 1.99 E+20
1: 1.9 E+20
0: 1.0 E+20

Loop 6
6: 1.999495 E+20
5: 1.99949 E+20
4: 1.9994 E+20
3: 1.999 E+20
2: 1.99 E+20
1: 1.9 E+20
0: 1.0 E+20

NaN tests
sqrt(-1) = NaN
0.0/0.0 = NaN
INFINITY*0 = NaN

INFINITY tests
1.0/0 = INF
1.0/-0 = -INF
1.0/0L = -INF
1.0/0UL = INF

tan(1.570796) = 1.633123 E+16
 
improved floating point test

Ok, I improved the test code I posted previously. This one allows you to print out all the available digits of precision (53 bits => 16 decimal digits) that "double" gives you on Teensy 3.

Code:
//
// Test of function that builds a C-style "string" for a floating point
// number in scientific notation.
//
// original by davekw7x December, 2010  
// http://arduino.cc/forum/index.php/topic,46931.0.html
// modified to use "double" and to run to smaller / larger values  March 12 2013 JPB
//

void setup()
{
    double f, fa;
    int d;
    Serial.begin(115200);
    delay(3000);
    Serial.println("double precision floating point test");

    f = 0.0;
    // No "digits" argument means 2 digits
    Serial.print("0.0 = ");Serial.println(double2s(f));Serial.println();
    
    // Rounding with leading zeros in the fractional part
    f = 10.3456;
    Serial.print(f,4);Serial.print(" = ");Serial.println(double2s(f, 4));Serial.println();
    
    /* 
       For loops 1 and 2, note that floating point
       overflows result values of"INF"
    */
    f = PI;

    
    Serial.println("Loop 1");
    for (int i=1; i< 58; i++)
    {
        Serial.println( double2s(f,16));
        f *=1E6;
    }
    Serial.println();

    f = -PI;
    Serial.println("Loop 2");
    for (int i=1; i< 58; i++)
    {
        Serial.println(double2s(f, 16));
        f *=1E6;
    }  
    Serial.println();

    /*
       For loops 3 and 4 note that floating point
       underflows result in values that go to zero.
    */
    f = PI;
    Serial.println("Loop 3");
    for (int i=1; i< 60; i++)
    {
        Serial.println(double2s(f, 16));
        f /= 1E6;
    }
    Serial.println();

    f = -PI;
    Serial.println("Loop 4");
    for (int i=1; i< 58; i++)
    {
        Serial.println(double2s(f, 16));
        f /= 1E6;
    }
    Serial.println();

    /*
       Loop 5 shows rounding as follows:
        6: 1.999518 E+20
        5: 1.99952 E+20
        4: 1.9995 E+20
        3: 2.000 E+20
        2: 2.00 E+20
        1: 2.0 E+20
        0: 2 E+20
    */

    f = 1.999518e20;
    Serial.println("Loop 5");
    for (int i = 16; i >= 0; i--) {
        Serial.print(i);Serial.print(": ");Serial.println(double2s(f, i));
    }
    Serial.println();
    
    /* 
       Loop 6 shows rounding as follows:
        6: 1.999496 E+20
        5: 1.99950 E+20
        4: 1.9995 E+20
        3: 1.999 E+20
        2: 2.00 E+20
        1: 2.0 E+20
        0: 2 E+2
    */
    
    f = 1.999496e20;
    Serial.println("Loop 6");
    for (int i = 16; i >= 0; i--) {
        Serial.print(i);Serial.print(": ");Serial.println(double2s(f, i));
    }    
    Serial.println();
    
    Serial.println("NaN tests");
    f = sqrt(-1);
    Serial.print("sqrt(-1) = ");Serial.println(double2s(f, 3));

    f = 0.0/0.0;
    Serial.print("0.0/0.0 = ");Serial.println(double2s(f, 4));

    f = INFINITY * 0;
    Serial.print("INFINITY*0 = ");Serial.println(double2s(f, 5));Serial.println();

    
    Serial.println("INFINITY tests");
    f = 1.0/0;
    Serial.print("1.0/0 = ");Serial.println(double2s(f, 1));
    //printBytes(f); 

    f = -1.0/0;
    Serial.print("1.0/-0 = ");Serial.println(double2s(f, 1)); 
    //printBytes(f); 

    f = -1.0/0L;
    Serial.print("1.0/0L = ");Serial.println(double2s(f, 2));
    
    f = 1.0/0UL;
    Serial.print("1.0/0UL = ");Serial.println(double2s(f, 3));
    
    Serial.println();
    
    // Note that tan(pi/2) may not result in INF due
    // to limited precision.
    //
    f = tan(HALF_PI);
    Serial.print("tan(");Serial.print(HALF_PI, 6);Serial.print(") = ");  
    Serial.println(double2s(f, 6));
}

void loop()
{
} 


// ====== double2s(): print out up to 16 digits of input double-precision value
// This version enables double-precision for Teensy 3, etc. 
// by J.Beale March 2013
// modified from original float2s() posted by davekw7x on December, 2010
// http://arduino.cc/forum/index.php/topic,46931.0.html

char * double2s(double f)
{
  return double2s(f, 2);
}

char * double2s(double f, unsigned int digits) {    
double fa;
int d;
static char s[26];  // formated number as string
int index=0;

  // handle sign
  if (f < 0.0)
  {
    s[index++] = '-';
    f = -f;
  } 
  // handle infinite values
  if (isinf(f))
  {
    strcpy(&s[index], "INF");
    return s;
  }
  // handle Not a Number
  if (isnan(f)) 
  {
    strcpy(&s[index], "NaN");
    return s;
  }

  // max digits
  if (digits > 16) digits = 16;
  int exponent = int(log10(f));
  double g = f / pow(10, exponent);
  if ((g < 1.0) && (g != 0.0))      
  {
    g *= 10;
    exponent--;
  }
  if (exponent < -324) {  // lower limit of double-precision on Teensy 3
    g = 0;
    exponent = 0;
  }
  if (digits < 16) {  // display number rounded at last digit
    g += 0.5 / pow(10,digits);
  }
  
  d = g;   
  sprintf(&s[index++],"%d",d);  
  sprintf(&s[index++],".");
  for (int i=0;i<digits;i++) {
      g = (g - d) * 10.0;  // shift one decimal place to the left
      d = int(g);
      sprintf(&s[index++],"%d",d);
  }
  sprintf(&s[index], " E%+d", exponent);
  return s;    
} // ===== end double2s()

Here is the T3.0 output:

Code:
double precision floating point test
0.0 = 0.00 E+0

10.3456 = 1.0346 E+1

Loop 1
3.1415926535897931 E+0
3.1415926535897931 E+6
3.1415926535897931 E+12
3.1415926535897926 E+18
3.1415926535897931 E+24
3.1415926535897926 E+30
3.1415926535897926 E+36
3.1415926535897931 E+42
3.1415926535897922 E+48
3.1415926535897922 E+54
3.1415926535897926 E+60
3.1415926535897931 E+66
3.1415926535897931 E+72
3.1415926535897926 E+78
3.1415926535897926 E+84
3.1415926535897926 E+90
3.1415926535897926 E+96
3.1415926535897926 E+102
3.1415926535897922 E+108
3.1415926535897926 E+114
3.1415926535897926 E+120
3.1415926535897926 E+126
3.1415926535897931 E+132
3.1415926535897931 E+138
3.1415926535897931 E+144
3.1415926535897931 E+150
3.1415926535897931 E+156
3.1415926535897931 E+162
3.1415926535897931 E+168
3.1415926535897926 E+174
3.1415926535897926 E+180
3.1415926535897926 E+186
3.1415926535897922 E+192
3.1415926535897922 E+198
3.1415926535897922 E+204
3.1415926535897917 E+210
3.1415926535897922 E+216
3.1415926535897922 E+222
3.1415926535897926 E+228
3.1415926535897922 E+234
3.1415926535897926 E+240
3.1415926535897922 E+246
3.1415926535897922 E+252
3.1415926535897922 E+258
3.1415926535897922 E+264
3.1415926535897926 E+270
3.1415926535897926 E+276
3.1415926535897926 E+282
3.1415926535897926 E+288
3.1415926535897926 E+294
3.1415926535897922 E+300
3.1415926535897922 E+306
INF
INF
INF
INF
INF

Loop 2
-3.1415926535897931 E+0
-3.1415926535897931 E+6
-3.1415926535897931 E+12
-3.1415926535897926 E+18
-3.1415926535897931 E+24
-3.1415926535897926 E+30
-3.1415926535897926 E+36
-3.1415926535897931 E+42
-3.1415926535897922 E+48
-3.1415926535897922 E+54
-3.1415926535897926 E+60
-3.1415926535897931 E+66
-3.1415926535897931 E+72
-3.1415926535897926 E+78
-3.1415926535897926 E+84
-3.1415926535897926 E+90
-3.1415926535897926 E+96
-3.1415926535897926 E+102
-3.1415926535897922 E+108
-3.1415926535897926 E+114
-3.1415926535897926 E+120
-3.1415926535897926 E+126
-3.1415926535897931 E+132
-3.1415926535897931 E+138
-3.1415926535897931 E+144
-3.1415926535897931 E+150
-3.1415926535897931 E+156
-3.1415926535897931 E+162
-3.1415926535897931 E+168
-3.1415926535897926 E+174
-3.1415926535897926 E+180
-3.1415926535897926 E+186
-3.1415926535897922 E+192
-3.1415926535897922 E+198
-3.1415926535897922 E+204
-3.1415926535897917 E+210
-3.1415926535897922 E+216
-3.1415926535897922 E+222
-3.1415926535897926 E+228
-3.1415926535897922 E+234
-3.1415926535897926 E+240
-3.1415926535897922 E+246
-3.1415926535897922 E+252
-3.1415926535897922 E+258
-3.1415926535897922 E+264
-3.1415926535897926 E+270
-3.1415926535897926 E+276
-3.1415926535897926 E+282
-3.1415926535897926 E+288
-3.1415926535897926 E+294
-3.1415926535897922 E+300
-3.1415926535897922 E+306
-INF
-INF
-INF
-INF
-INF

Loop 3
3.1415926535897931 E+0
3.1415926535897935 E-6
3.1415926535897931 E-12
3.1415926535897935 E-18
3.1415926535897935 E-24
3.1415926535897935 E-30
3.1415926535897935 E-36
3.1415926535897940 E-42
3.1415926535897940 E-48
3.1415926535897940 E-54
3.1415926535897940 E-60
3.1415926535897948 E-66
3.1415926535897948 E-72
3.1415926535897948 E-78
3.1415926535897948 E-84
3.1415926535897940 E-90
3.1415926535897940 E-96
3.1415926535897940 E-102
3.1415926535897948 E-108
3.1415926535897948 E-114
3.1415926535897948 E-120
3.1415926535897953 E-126
3.1415926535897953 E-132
3.1415926535897953 E-138
3.1415926535897953 E-144
3.1415926535897948 E-150
3.1415926535897948 E-156
3.1415926535897948 E-162
3.1415926535897948 E-168
3.1415926535897948 E-174
3.1415926535897948 E-180
3.1415926535897948 E-186
3.1415926535897948 E-192
3.1415926535897948 E-198
3.1415926535897948 E-204
3.1415926535897948 E-210
3.1415926535897953 E-216
3.1415926535897948 E-222
3.1415926535897948 E-228
3.1415926535897948 E-234
3.1415926535897948 E-240
3.1415926535897953 E-246
3.1415926535897948 E-252
3.1415926535897953 E-258
3.1415926535897948 E-264
3.1415926535897953 E-270
3.1415926535897948 E-276
3.1415926535897953 E-282
3.1415926535897948 E-288
3.1415926535897948 E-294
3.1415926535897948 E-300
3.1415926535897948 E-306
3.1415926535886367 E-312
3.1415897941871211 E-318
5.0000000000000000 E-324
0.0000000000000000 E+0
0.0000000000000000 E+0
0.0000000000000000 E+0
0.0000000000000000 E+0

Loop 4
-3.1415926535897931 E+0
-3.1415926535897935 E-6
-3.1415926535897931 E-12
-3.1415926535897935 E-18
-3.1415926535897935 E-24
-3.1415926535897935 E-30
-3.1415926535897935 E-36
-3.1415926535897940 E-42
-3.1415926535897940 E-48
-3.1415926535897940 E-54
-3.1415926535897940 E-60
-3.1415926535897948 E-66
-3.1415926535897948 E-72
-3.1415926535897948 E-78
-3.1415926535897948 E-84
-3.1415926535897940 E-90
-3.1415926535897940 E-96
-3.1415926535897940 E-102
-3.1415926535897948 E-108
-3.1415926535897948 E-114
-3.1415926535897948 E-120
-3.1415926535897953 E-126
-3.1415926535897953 E-132
-3.1415926535897953 E-138
-3.1415926535897953 E-144
-3.1415926535897948 E-150
-3.1415926535897948 E-156
-3.1415926535897948 E-162
-3.1415926535897948 E-168
-3.1415926535897948 E-174
-3.1415926535897948 E-180
-3.1415926535897948 E-186
-3.1415926535897948 E-192
-3.1415926535897948 E-198
-3.1415926535897948 E-204
-3.1415926535897948 E-210
-3.1415926535897953 E-216
-3.1415926535897948 E-222
-3.1415926535897948 E-228
-3.1415926535897948 E-234
-3.1415926535897948 E-240
-3.1415926535897953 E-246
-3.1415926535897948 E-252
-3.1415926535897953 E-258
-3.1415926535897948 E-264
-3.1415926535897953 E-270
-3.1415926535897948 E-276
-3.1415926535897953 E-282
-3.1415926535897948 E-288
-3.1415926535897948 E-294
-3.1415926535897948 E-300
-3.1415926535897948 E-306
-3.1415926535886367 E-312
-3.1415897941871211 E-318
-5.0000000000000000 E-324
0.0000000000000000 E+0
0.0000000000000000 E+0

Loop 5
16: 1.9995179999999999 E+20
15: 1.999518000000000 E+20
14: 1.99951800000000 E+20
13: 1.9995180000000 E+20
12: 1.999518000000 E+20
11: 1.99951800000 E+20
10: 1.9995180000 E+20
9: 1.999518000 E+20
8: 1.99951800 E+20
7: 1.9995180 E+20
6: 1.999518 E+20
5: 1.99952 E+20
4: 1.9995 E+20
3: 2.000 E+20
2: 2.00 E+20
1: 2.0 E+20
0: 2. E+20

Loop 6
16: 1.9994959999999998 E+20
15: 1.999496000000000 E+20
14: 1.99949600000000 E+20
13: 1.9994960000000 E+20
12: 1.999496000000 E+20
11: 1.99949600000 E+20
10: 1.9994960000 E+20
9: 1.999496000 E+20
8: 1.99949600 E+20
7: 1.9994960 E+20
6: 1.999496 E+20
5: 1.99950 E+20
4: 1.9995 E+20
3: 1.999 E+20
2: 2.00 E+20
1: 2.0 E+20
0: 2. E+20

NaN tests
sqrt(-1) = NaN
0.0/0.0 = NaN
INFINITY*0 = NaN

INFINITY tests
1.0/0 = INF
1.0/-0 = -INF
1.0/0L = -INF
1.0/0UL = INF

tan(1.570796) = 1.633124 E+16

EDIT: slightly later version of this same code also uploaded here: http://arduino.cc/forum/index.php?topic=153909.0
 
Last edited:
Status
Not open for further replies.
Back
Top