0

I have made a function that convert format of latitude and longitude from Degrees Minutes.m to Decimal Degrees.

For example:

latitude = 3130.1245 (Degrees Minutes.m) == 31.502075 (Decimal Degrees)

The problem is that I call this function twice with the same argument but it returns two different results. How is this happening?

Here is my code:

  double Format(char *array){
  double Degrees = 10*(array[0]-'0')+(array[1]-'0');
  int i;
  double z=0,N=10;
  double x =0;
  for(i=2;array[i]!='\0';i++){

      if(array[i]=='.'){
          for(i=i+1;array[i]!='\0';i++){
              z=z+((array[i]-'0')/N);
              N=N*10;
                      }
      }
      else
      x=x*10+(array[i]-'0');
  }
   double Minutes = (x+z)/60 ;
  return Degrees+Minutes ;
  }

int main(){
char lat[]="3031.1234"; 
char lon[]="3031.1234"; 
double latitude ;
double longitude ;
latitude =  Format(lat);
longitude =  Format(lon);
printf("%lf\n",latitude);  // output : 30.518723
printf("%lf\n",longitude); // output : 5247.185390
return 0 ;
}
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • 2
    I cannot reproduce your error with following code – Iłya Bursov May 01 '15 at 22:15
  • I tested your code and it worked fine. – issathink May 01 '15 at 22:16
  • 1
    You don't need `%lf` to print a `double`, you just need `%f`. – Weather Vane May 01 '15 at 22:22
  • finally reproduced - you need to add `break;` just after inner loop – Iłya Bursov May 01 '15 at 22:24
  • How will you deal with 3-digit numbers of degrees (longitudes in the range -180..-100 and +100..+180)? – Jonathan Leffler May 01 '15 at 22:26
  • @JonathanLeffler : yes i have to change the code in case of longitude, in order to take the first three characters of the array as the Degree value, – Abdelrahman Tarief May 01 '15 at 22:33
  • @JonathanLeffler : but still don't know how to make this function compatible with both lat. and lon. – Abdelrahman Tarief May 01 '15 at 22:34
  • I think you'll need to count the digits before the decimal point. If the number is one or two digits, you're very close to (0, 0). If the number is 3-5, then you've got 1-3 digits of degrees and 2 digits of minutes (plus the fractional bit). If there are any more, someone is misformatting the data and it should be rejected with an error. – Jonathan Leffler May 01 '15 at 22:39
  • YW. I would think carefully about using `strtol()` to isolate the number before the decimal point as an integer, and then doing integer arithmetic to determine the values (beware negative numbers), followed by `strtod()` to convert the fraction. Beware, `.1` and `.0001` are very different fractions, but if you try doing integer arithmetic after the decimal point naively, you will end up treating them the same. – Jonathan Leffler May 02 '15 at 00:28
  • You might find [Ignore E when reading `double` with `sscanf()`](http://stackoverflow.com/questions/29563849/) helpful, or the question linked. Not an exact answer for your (rather weird) data format. – Jonathan Leffler May 02 '15 at 00:35
  • `z=z+((array[i]-'0')/N);` is surely a logic error. It will add zero for all possible digits (`1/10` is `0` etc.) – M.M May 02 '15 at 00:51
  • Using the `strtod` function instead of this manual conversion would make your job a lot easier – M.M May 02 '15 at 00:51
  • the format() function fails when passed east longitudes (negative) or south latitudes (negative). It also fails with longitudes greater than 99.9999 degrees. It also fails when the position is less than 10 degrees. suggest a major re-design of the function – user3629249 May 02 '15 at 20:17
  • the code processes characters past the end of the input data array. That is why the output is inconsistent. suggest set flag to exit outer loop when '\0' is encountered in either inner loop or outer loop – user3629249 May 02 '15 at 20:24
  • when writing code, for all indentation, do not use tabs, (suggest 4 spaces). indent after every opening brace '{' un-indent before every closing brace '}' Do not use tabs because each editor/wordprocessor has the tab width/tab stops set differently. This 'tabs' problem is very obvious in the posted code – user3629249 May 02 '15 at 20:28

1 Answers1

4

Could it be that

  • the inner loop ends with i pointing at 0;
  • then there is i++ in the outer loop;
  • leading to access of elements outside of the array border (and undefined behavior)?
AlexD
  • 32,156
  • 3
  • 71
  • 65
  • array[i]!='\0' , this condition will terminate the outer loop when the inner loop finish its work . – Abdelrahman Tarief May 01 '15 at 22:22
  • 1
    And a plausible fix would be a `break` before the end of the `if` around the inner loop, I think. – Jonathan Leffler May 01 '15 at 22:22
  • @AbdelrahmanTarief: yes, but then the outer loop increments `i` beyond the end of the array, hence the indeterminate behaviour. – Jonathan Leffler May 01 '15 at 22:22
  • and i am asking how could be the output different when the input is equal ? – Abdelrahman Tarief May 01 '15 at 22:22
  • @AbdelrahmanTarief: the outputs are different because the data following the arrays is different. There's a moderate chance that one string has the second copy immediately after it, and this affects the calculation one way, while the second has some other data after it, yielding a different answer. – Jonathan Leffler May 01 '15 at 22:24