Atof() Precision is not accurate

Hi everyone,
I wrote this simple sketch to getting float value from long.

void floatlon(long longitude) {
  char LongitudeD[4] = "";
  char LongitudeM[9] = "";
  char floatlongitude[15] = "";
  LongitudeD[0] = (longitude / 10000000000) + '0';
  LongitudeD[1] = ((longitude % 10000000000) / 1000000000) + '0';
  LongitudeD[2] = ((longitude % 1000000000) / 100000000) + '0';

  LongitudeM[0] = ((longitude % 100000000) / 10000000) + '0';
  LongitudeM[1] = ((longitude % 10000000) / 1000000) + '0';
  LongitudeM[2] = ((longitude % 1000000) / 100000) + '0';
  LongitudeM[3] = ((longitude % 100000) / 10000) + '0';
  LongitudeM[4] = ((longitude % 10000) / 1000) + '0';
  LongitudeM[5] = ((longitude % 1000) / 100) + '0';
  LongitudeM[6] = ((longitude % 100) / 10) + '0';
  LongitudeM[7] = ((longitude % 10)) + '0';

  floatlongitude[0] = LongitudeD[0];
  floatlongitude[1] = LongitudeD[1];
  floatlongitude[2] = LongitudeD[2];
  floatlongitude[3] = '.';
  floatlongitude[4] = LongitudeM[0];
  floatlongitude[5] = LongitudeM[1];
  floatlongitude[6] = LongitudeM[2];
  floatlongitude[7] = LongitudeM[3];
  floatlongitude[8] = LongitudeM[4];
  floatlongitude[9] = LongitudeM[5];
  floatlongitude[10] = LongitudeM[6];
  floatlongitude[11] = LongitudeM[7];

  Serial.println(LongitudeM);
  Serial.print("Float ");
  float qq = atof(floatlongitude);
  Serial.println(qq, 8);
}

I didn't use dividing methods because Arduino haven't much precision least 8 digits. So I added long values as char array and getting it as float using atof() function. When I calling this function using 8012345678 it giving me as following result.

12345678
Float 8.12345695

It should be Float 8.12345678. but atof() is giving me wrong value. How can I fix this problem. I need least 8 digits accurate value for my calculation.
Thank You.

Perhaps this will help:

The accuracy of the float is limited by 6-7 digits, include the integer part.
Perhaps the using longitude values as integer will a solution

Use an Arduino that supports type double, that is, not an AVR-based Arduino like Uno, "Classic" Nano, Mega, etc.

Please note that value is NOT a valid long value, which should not exceed 2,147,483,647. You mean 812345678 I suppose.

Anyway, first of all you don't need all that crap code to convert the long into a float, you just need one single line:

float f = longitude/100000000.0;

But you'll get the same result.
As said, you can't have float values with 8 digits precision on Uno, but if we're talking about GPS positioning I don't know what the rest of the code does, but are you sure you need such a single float value, instead of converting it into a dd°mm'ss"string, for example?

(post deleted by author)

Please do not cross post.

Declare variables to be of type double, instead of float. Only with AVR-based Arduinos is "double" treated the same as "float"

1 Like

I have merged your cross-posts @Indula_Karunathilaka1.

Cross-posting is against the Arduino forum rules. The reason is that duplicate posts can waste the time of the people trying to help. Someone might spend a lot of time investigating and writing a detailed answer on one topic, without knowing that someone else already did the same in the other topic.

Repeated cross-posting can result in a suspension from the forum.

In the future, please only create one topic for each distinct subject matter. This is basic forum etiquette, as explained in the "How to get the best out of this forum" guide. It contains a lot of other useful information. Please read it.

Thanks in advance for your cooperation.

1 Like

Work separately with integer and fractional parts.
When you calculate the average, use only digits after the point, treating it as integers:

89.1234567 => 1234567
89.1234533 => 1234533
89.1234777 => 1234777

Get the average from (1234567 + 1234533 + 1234777) , it will be 1234625 - and use this digits as fraction part of your average longitude =>89.1234625

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.