String() function seems to be rounding doubles?

Hi everyone,

I have a simple issue here that has me puzzled; the following code should illustrate it.

double d = 12345.678910;

Serial.println(d, 6);     // prints "12345.678910"

String dstring = String(d, 6);

Serial.println(dstring);  // prints "12345.679000"

In other words, when I call the String() function and pass it a double, it seems to round the double to three decimal places before generating the string from it. I'm running this on an AtMEGA 2560.

Is there a different function I should use if I want more decimal places to be preserved when I convert my double to a string?

Thanks!

'double' is not supported straightforwardly in GCC-AVR. It is an alias for 'float' which is a 32 bit or roughly 6 digit accuracy only. Some Arduinos with 32 bit processors do support full 64 bit floating point variables.

Here's an extension to this question:

if I do something ridiculous like

double d = 12345.67890123456789123456;
Serial.println(d, 20);

I get something like the following in the serial monitor (plus or minus a digit after the decimal point): 12345.67890123450000000000 (truncated at roughly the 9th or so digit after the decimal point, with zeroes following).

This seems to indicate to me that the precision is there for what I need for my purposes (four or five digits after the decimal point), and that the String() function is doing something odd to the double that I pass into it.

Am I fooling myself with the serial monitor somehow?

No, but you may be fooling yourself about your expectations of 32 bit IEEE754.

223 = 8388608

AEE297:
This seems to indicate to me that the precision is there for what I need for my purposes (four or five digits after the decimal point)

...only if the integer part is 1 digit. It is called "floating point" because the decimal point FLOATS! It is the total number of digits that remains the same. 123456.7 has the same precision as 1.234567 !

How is it then that when I print it in the serial monitor it seems to have around 9 or 10 digits of precision after the decimal point?

Emphasis on "it seems"...

AEE297:
How is it then that when I print it in the serial monitor it seems to have around 9 or 10 digits of precision after the decimal point?

The default is 2 decimal places. You specified 6. The robot did what you told it to do.

Right. How could it transmit 10 digits after the decimal point to be displayed on the serial monitor if it doesn't have precision out that far?

Because you asked it to.

It did its best.

AEE297:
Right. How could it transmit 10 digits after the decimal point to be displayed on the serial monitor if it doesn't have precision out that far?

It fabricates them. If you want to believe that it is proof that the precision is real, good luck to you.

I see. It only has precision to the first 8 digits and just makes up the rest or something. The "making up the rest" part was what was confusing me. I would have naively expected say 8 significant digits followed by zeroes if the precision were only to 8 significant digits for instance.

Looks like I'll need to use unsigned longs instead and do something more complicated.

AEE297:
Looks like I'll need to use unsigned longs instead and do something more complicated.

Why unsigned?