1

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[10];
 msg.toCharArray(buf, 19);
 double num = 0.0;
 int c;
 c = buf[0] - '0';
 double num0 = (c * 1000);
 c = buf[1] - '0';
 double num1 = (c * 100);
 c = buf[2] - '0';
 double num2 = (c * 10);
 c = buf[3] - '0';
 double num3 = (c * 1);
 c = buf[5] - '0';
 double num5 = (c * 0.1);
 c = buf[6] - '0';
 double num6 = (c * 0.01);
 c = buf[7] - '0';
 double num7 = (c * 0.001);
 c = buf[8] - '0';
 double num8 = (c * 0.0001);
 c = buf[9] - '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 :=)

asked May 22, 2020 at 23:22

3 Answers 3

3

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.

answered May 22, 2020 at 23:29
2
  • 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 :) Commented May 23, 2020 at 8:32
  • @Benjamin_Ellmer: Maybe store the integer and fractional parts separately? Commented May 23, 2020 at 8:40
1

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.

answered May 23, 2020 at 9:12
1
  • 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 Commented May 24, 2020 at 18:07
0

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.

answered May 23, 2020 at 15:58
1
  • 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. Commented May 23, 2020 at 17:12

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.