Convert dms to dd

This is a discussion on Convert dms to dd within the C Programming forums, part of the General Programming Boards category; Hello, I'm using the Pacific C for MS-DOS, v7.51 compiler from HI-TECH software. A function I wrote previously on the ...

  1. #1
    Registered User
    Join Date
    Jun 2007
    Posts
    8

    Convert dms to dd

    Hello,

    I'm using the Pacific C for MS-DOS, v7.51 compiler from HI-TECH software. A function I wrote previously on the Microsoft Visual C++ 6.0 Professional Edition does not output the correct results.

    Code:
       #include <stdio.h>
       #include <math.h>
                     
       double dms(double);   /* Convert deg.mmss to decimal degrees */
    
       main()
       {
       }
    
       double dms(double dd)
       {
          double dms = 0, mind = 0, secd = 0;
          int hr = 0, min = 0, sec = 0;
    
          dms = dd;
          hr = (int) dms;
          min = (int) ((dms - hr) * 100 + 1.e-6);
          sec = (int) (dms * 10000 + 1.e-6) % 100;
          mind = (double) min / 60;
          secd = (double) sec / 3600;
          dd = hr + mind + secd;
    
          return dd;
       }
    The inclusion of "+ 1.e-6" was suggested to me because when I executed the function on the Microsoft compiler the results weren't always correct. I was told the "+ 1.e-6" would add some "junk" to the output. Now, when I execute the same code on the HI-TECH compiler, I do not get the correct results.

    Examples:

    Input Output Should Be

    36.5212 36.86555556 36.87000000

    45.0000 44.98555556 45.00000000

    Merci,

    Jacques

  2. #2
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Your program needs to call the function!

    To get more help, include your input and print statements.

  3. #3
    Registered User
    Join Date
    Jun 2007
    Posts
    8
    Thanks very much for responding to my post! If you would add a variable containing the double 36.5212 and call the function in your compiler you would see what I am talking about. I don't know if this problem is unique to the Pacific C compiler or what.

  4. #4
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    I don't have that compiler, so I can't say if it's a compiler problem.

    I'm not that familiar with radian to degree conversion, but in checking it out, I see equations like this:

    "
    Because it is the case that 1 deg = pi rad/180 and 1 rad = 180 deg/pi, we have the following conversion rules.

    * To convert from degrees to radians, multiply degrees by (pi rad)/(180 deg).

    * To convert from radians to degrees, multiply radians by (180 deg)/(pi rad).
    "
    But when I look at the math in your function, I see "happy feet" type math. Lots of dancing around, including a "fudge" factor, "just because...".



    If you google "degree to radian", you'll get a whole page of hits. I'd recommend using another algorithm for the conversion, entirely. One with real clarity and definitely no "fudge factors".

    Good luck.

  5. #5
    Registered User
    Join Date
    May 2007
    Posts
    58
    Quote Originally Posted by Adak View Post
    I don't have that compiler, so I can't say if it's a compiler problem.

    I'm not that familiar with radian to degree conversion, but in checking it out, I see equations like this:



    But when I look at the math in your function, I see "happy feet" type math. Lots of dancing around, including a "fudge" factor, "just because...".



    If you google "degree to radian", you'll get a whole page of hits. I'd recommend using another algorithm for the conversion, entirely. One with real clarity and definitely no "fudge factors".

    Good luck.
    He's not trying to convert gradians to degrees.

    I think that what he's trying to do is like this:

    angle = 40.4559
    would be 40 degrees, 45 minutes, 59 seconds

    and then convert that to decimal

    that would be:

    40,76638.

  6. #6
    Registered User
    Join Date
    Jun 2007
    Posts
    8
    Thanks Adak and Govalant for the replies! I wrote the above code because I couldn't find what I needed in the <time.h> library. I figured a dms to dd conversion and visa versa would be in there. I then thought about converting a number to a string and picking it apart into substrings. Since I'm just a neophyte programmer I didn't know how to do that.

  7. #7
    Registered User
    Join Date
    Jan 2005
    Posts
    51
    If you get a working solution to this, please post it. I'm curious as to how you solve this problem. I work on surveying programs, so this particular problem, although not great, is problematic enough to where I created my own data structure and routines just to get around it. Anyway, I suggest using floor() instead of casting to get your integer parts since in some cases it might round up.

    I think the problem lies in the way a float or double is represented so when you multiply by 100 expecting to move the decimal place a couple of places then get the integer part, you don't always get the expected result. In calculators, they use bcd (binary coded decimal) to get around this problem, and it seems to work. The thing with the strings might work.

    Hope you get it working.

  8. #8
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    This is what I found with Google's help:
    How To Convert a Decimal to Sexagesimal

    You'll often find degrees given in decimal degrees (121.135&#176 instead of the more common degrees, minutes, and seconds (121&#176;8'6"). However, it's easy to convert from a decimal to the sexagesimal system.

    Here's How:

    1. The whole units of degrees will remain the same (i.e. in 121.135&#176; longitude, start with 121&#176.
    2. Multiply the decimal by 60 (i.e. .135 * 60 = 8.1).
    3. The whole number becomes the minutes (8').
    4. Take the remaining decimal and multiply by 60. (i.e. .1 * 60 = 6).
    5. The resulting number becomes the seconds (6"). Seconds can remain as a decimal.
    6. Take your three sets of numbers and put them together, using the symbols for degrees (&#176, minutes (‘), and seconds (") (i.e. 121&#176;8'6" longitude)

    Tips:

    1. Though there are 360 degrees in a circle, each degree is divided into sixty minutes and each minute is divided into sixty seconds.
    So geography and surveying are more exciting than we thought {{ Sexagesimal }}
    Last edited by Adak; 06-05-2007 at 02:05 PM.

  9. #9
    Registered User
    Join Date
    Jun 2007
    Posts
    8
    This is getting more interesting by the day! "Lay of the land" is my favorite surveying term! All kidding aside, I wrote the dms function because it was part of a horizontal curve solver program for land surveying. I wrote the function w/o the extra + 1.e-6 tacked on and checked a lot of conversions on my HP-48 calculator. I did not always get the correct results. I showed the dms function to a former CS professor and she suggested I add the + 1.e-6. All of the conversions were correct then. If anyone would like the dd function or the horizontal curve solver program please let me know. I'll be happy to post it!

  10. #10
    Registered User
    Join Date
    Jan 2005
    Posts
    51
    Quote Originally Posted by JacquesLeJock View Post
    and checked a lot of conversions on my HP-48 calculator.
    This is interesting. I do exactly the same thing. When in doubt, I get out the 48!

    Also, I wish I had a CS professor to confer with. Lucky guy.

  11. #11
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    This works in very limited testing. Tenths of Seconds are rounded downward, always.


    Code:
    #include <stdio.h>
    
    
    int main()  {
       int i, degree, sec;
       long min;
       double original, doublemin;
    
       printf("\n\n\n Enter original number in degree's: ");
       scanf("&#37;lf", &original);
    
       /* for testing: original = 121.135; Correct Answer is 121 degrees, 8' 6" */
    
       degree = original;
       doublemin = original - degree;
       doublemin *= 60;
    
       min = doublemin;
       doublemin -= min;
       doublemin *= 60;
      
       sec = doublemin;
       printf("\n\n Decimal %f Equals Sexagesimal %d%c %ld' %d\"", \
       original, degree, 248, min, sec);
    
       fseek(stdin, 0L, SEEK_END);
       /* while ((i = getchar()) != '\n'); */
       printf("\n\n Program Complete. Hit Enter to Quit "); 
       i = getchar();
    
       return (i == 0 ? i : 0);
    }
    Don't forget the 'l' in "%ld", or you'll get wrong answers printed out.

    This site will help test your own program's answers:
    http://www.fcc.gov/mb/audio/bickel/DDDMMSS-decimal.html

    Although it has a field for both longitude and latitude, you don't need to fill in both. Just one will do.
    Last edited by Adak; 06-05-2007 at 05:27 PM.

  12. #12
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,590
    If you want to maintain accuracy, then you need to read the value into a better data structure (not a float) in the first place.

    Just because you can lazily read 36.5212 into a float doesn't mean it's the right thing to do.

    Code:
    struct posn {
      int deg, min, sec;
    };
    Then carefully pick apart you input to assign 36, 52 and 12 to the respective members of the struct.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  13. #13
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Quote Originally Posted by Salem View Post
    If you want to maintain accuracy, then you need to read the value into a better data structure (not a float) in the first place.

    Just because you can lazily read 36.5212 into a float doesn't mean it's the right thing to do.

    Code:
    struct posn {
      int deg, min, sec;
    };
    Then carefully pick apart you input to assign 36, 52 and 12 to the respective members of the struct.
    Good advice, thanks Salem. I do very little programming with floats. I only tested the program on three values, so anyone running it should give it a lot more testing and make the changes mentioned above.

  14. #14
    Registered User
    Join Date
    Jun 2007
    Posts
    8
    Thanks again Adak and also Salem for your posts.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Another syntax error
    By caldeira in forum C Programming
    Replies: 31
    Last Post: 09-05-2008, 01:01 AM
  2. reading a file into a block
    By mickey0 in forum C++ Programming
    Replies: 19
    Last Post: 05-03-2008, 05:53 AM
  3. Back To The Basics: Freeing An Array on the Heap?
    By Deo in forum C++ Programming
    Replies: 12
    Last Post: 04-07-2007, 04:42 AM
  4. Convert Char to Int Function
    By drdroid in forum C++ Programming
    Replies: 9
    Last Post: 02-19-2003, 11:53 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21