# Arduino parsing Double is incorrect

Im having some problems with parsing gps coordinates with the arduino ide.

To be honest I want to process the data without a library.

From my sensor I get this String: 4815.98450

The result of String.toDouble(): 4815.9843750

I also parsed it on my own, but i got the same result: (yes this code is not nice ;))

``````char buf;
msg.toCharArray(buf, 19);
double num = 0.0;

int c;

c = buf - '0';
double num0 = (c * 1000);
c = buf - '0';
double num1 = (c * 100);
c = buf - '0';
double num2 = (c * 10);
c = buf - '0';
double num3 = (c * 1);
c = buf - '0';
double num5 = (c * 0.1);
c = buf - '0';
double num6 = (c * 0.01);
c = buf - '0';
double num7 = (c * 0.001);
c = buf - '0';
double num8 = (c * 0.0001);
c = buf - '0';
double num9 = (c * 0.00001);
num = num + num0;
num = num + num1;
num = num + num2;
num = num + num3;
num = num + num5;
num = num + num6;
num = num + num7;
num = num + num8;
num = num + num9;
``````

Does somebody have a solution for my problems?

Thank you very much :=)

## 3 Answers

There is no easy solution. The Arduino you are using does not support double precision floating point. The type `double` is just an alias for `float`, which has 24-bit accuracy.

Your program is actually giving you the correct result, as the float closest to 4815.98450 is exactly 4815.984375.

• Thank you for your answer! You helped me a lot because now i know it is no bug. But now im searching for a workaround :) – Benjamin_Ellmer May 23 '20 at 8:32
• @Benjamin_Ellmer: Maybe store the integer and fractional parts separately? – Edgar Bonet May 23 '20 at 8:40

`double` (or float) is just an inappropriate data type.

Perhaps you take int(4815) and float(0.98450) as two numbers?

And BTW, I bet from your sensor you don't get a String object.

• Im reading the output from the TX of my sensor, so im pretty sure this is a string ;) i figured out that i can do my calculation without the first 2 digits of the number. there are some cases where it does not work but those cases are very unlikely – Benjamin_Ellmer May 24 '20 at 18:07

You can convert this to a long, do your arithmetic, and convert it back to an ASCII-Decimal number:

Remove the decimal point from the string. Convert the remaining string of digits to a long. Now you have the coordinate in binary, in units of the least significant decimal digit; 1 lsb == 0.00001, if you used 5 decimal places.

Manipulate your data however you need to using long integer arithmetic.

Divide the value by 10^ -(# of fraction digits you used). The quotient is the whole number part; the remainder is the fractional part. Print the quotient and a decimal point. Print the remainder padding with zeros to the left as necessary to result in your printing (# of fraction digits you used) total fraction digits.

The output conversion is even easier if you're willing to use sprintf():
Divide the value by 10^ -(# of fraction digits you used), as above. Let's assume 5 places as in your example:

``````char buffer[BIGENOUGH+1];
sprintf(buffer, "%ld.%05ld", value/100000, value%100000);
``````

Note that I made two divisions to get the quotient and the remainder and assumed you could tolerate the performance hit. If you're expecting to crank out a lot of values and speed is a factor, you could look up or write a division routine that can return both the quotient and the remainder results from a single division.

Update: @edgar_bonet points out that the compiler is smart enough to notice this fragment uses both results of the numerically same division and avoids dividing twice after all.

• Re the “routine that can return both the quotient and the remainder results from a single division”: this is exactly what avr-gcc does when compiling the example you provided. – Edgar Bonet May 23 '20 at 17:12