rounding with dtostrf


hi experts.

may i'm getting wrong, but....here i'm trying do:

double mynum;

mynum=45.816242;
dtostrf(mynum,8,6,buff1);
sprintf(buff, "%s", buff1);
serial.println(buff);


the result 45.816238. i'd expect @ least 45.816241 or 45.816243, rounding, why difference of 4?
i compiled arduino 1.6.5.

thanks suggestions....



hi experts.

may i'm getting wrong, but....here i'm trying do:

double mynum;

mynum=45.816242;
dtostrf(mynum,8,6,buff1);
sprintf(buff, "%s", buff1);
serial.println(buff);


the result 45.816238. i'd expect @ least 45.816241 or 45.816243, rounding, why difference of 4?
i compiled arduino 1.6.5.

thanks suggestions....

floating point in avr-gcc rather limited , in fact float, double , long double same.

if try little sketch below. it's best c book i've ever owned called "practical c programming" steve qualline.  show limitations of fp math in avr/arduino.

code: [select]
// floating point accuracy test - cow book page 271

void setup (void)
{
serial.begin (115200);

char buffer[64];
const char *mask0 = "data type = %s (%d bytes)\r\n";
const char *mask1 = "%3d digits accuracy in calculations\r\n";
const char *mask2 = "%3d digits accuracy in storage\r\n\r\n";
int counter;
float fnumber1, fnumber2, fresult;
double dnumber1, dnumber2, dresult;
long double lnumber1, lnumber2, lresult;

serial.print ("floating point accuracy test \"practical c programming\"\r\n");
serial.print ("3rd. ed. steve qualline, page 271, example 16-1 \"float.c\"\r\n\r\n");

sprintf (buffer, mask0, "float", sizeof (float));
serial.print (buffer);

fnumber1 = 1.0;
fnumber2 = 1.0;
counter = 0;

while (fnumber1 + fnumber2 != fnumber1) {
counter++;
fnumber2 /= 10.0;
}

sprintf (buffer, mask1, counter);
serial.print (buffer);

fnumber1 = 1.0;
fnumber2 = 1.0;
counter = 0;

while (1) {
fresult = fnumber1 + fnumber2;

if (fresult == fnumber1) {
break;
}

counter++;
fnumber2 /= 10.0;
}

sprintf (buffer, mask2, counter);
serial.print (buffer);

sprintf (buffer, mask0, "double", sizeof (double));
serial.print (buffer);

dnumber1 = 1.0;
dnumber2 = 1.0;
counter = 0;

while (dnumber1 + dnumber2 != dnumber1) {
counter++;
dnumber2 /= 10.0;
}

sprintf (buffer, mask1, counter);
serial.print (buffer);

dnumber1 = 1.0;
dnumber2 = 1.0;
counter = 0;

while (1) {
dresult = dnumber1 + dnumber2;

if (dresult == dnumber1) {
break;
}

counter++;
dnumber2 /= 10.0;
}

sprintf (buffer, mask2, counter);
serial.print (buffer);

sprintf (buffer, mask0, "long double", sizeof (long double));
serial.print (buffer);

lnumber1 = 1.0;
lnumber2 = 1.0;
counter = 0;

while (lnumber1 + lnumber2 != lnumber1) {
counter++;
lnumber2 /= 10.0;
}

sprintf (buffer, mask1, counter);
serial.print (buffer);

lnumber1 = 1.0;
lnumber2 = 1.0;
counter = 0;

while (1) {
lresult = lnumber1 + lnumber2;

if (lresult == lnumber1) {
break;
}

counter++;
lnumber2 /= 10.0;
}

sprintf (buffer, mask2, counter);
serial.print (buffer);
}

void loop (void)
{
// nothing
}



by way, produces on arduino board:

floating point accuracy test "practical c programming" 
3rd. ed. steve qualline, page 271, example 16-1 "float.c" 
 
data type = float (4 bytes) 
  8 digits accuracy in calculations 
  8 digits accuracy in storage 
 
data type = double (4 bytes) 
  8 digits accuracy in calculations 
  8 digits accuracy in storage 
 
data type = long double (4 bytes) 
  8 digits accuracy in calculations 
  8 digits accuracy in storage 



...and gcc on 64 bit linux machine:


floating point accuracy test "practical c programming"
3rd. ed. steve qualline, page 271, example 16-1 "float.c"

data type = float (4 bytes)
  8 digits accuracy in calculations
  8 digits accuracy in storage

data type = double (8 bytes)
 16 digits accuracy in calculations
 16 digits accuracy in storage

data type = long double (16 bytes)
 20 digits accuracy in calculations
 20 digits accuracy in storage


then again, atmega isn't quad core intel processor...... 


Arduino Forum > Using Arduino > Programming Questions > rounding with dtostrf


arduino

Comments