//
// 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()