Degrees To Radians To Degrees

May 5, 2015

There are 60 seconds in a minute, 60 minutes in a degree, and 180 / π = 57.2957795 degrees in a radian:

(define (degrees->radians deg min sec)
  (/ (+ deg (/ min 60) (/ sec 60 60)) 57.2957795))

(define (radians->degrees rad)
  (let* ((r (* rad 57.2957795))
         (d (floor r))
         (m (floor (* (- r d) 60)))
         (s (round (* (- (* (- r d) 60) m) 60))))
    (values (inexact->exact d)
            (inexact->exact m)
            (inexact->exact s))))

And here are some examples:

> (degrees->radians 47 6 38)
0.822234307
> (radians->degrees 0.82234307)
47
6
38

You can run the program at http://ideone.com/sc5uzT. I’ve pretty much given up responding on the forums, which makes me sad, but there is just too much vitriol for me. I give good, correct answers, and people who want to aggrandize themselves at the expense of others tell me my Python answer is no good because I used a two-space indent where the standard is four spaces, or my C answer is no good because my main function returned void instead of int, or my answer looks good but it’s in C and they only speak C++ (which at the level of the answer I gave was identical), or some other damn fool thing that certainly doesn’t help the original poster who is just trying to learn to program. So now I just read the forums from time to time as a way to find the kinds of questions that people find interesting and useful. As I said, that’s sad.

Pages: 1 2

One Response to “Degrees To Radians To Degrees”

  1. matthew said

    Trickier than it looks: in your solution, the use of round can result in a 60 in the seconds count for eg. 0.82234 radians (not the mention the problem of negative inputs).

    Two solutions, this one seems more elegant: multiply out to the smallest quantity, round and then divide back out:

    void r2dms(float r, int &d, int &m, int &s)
    {
      int n = round(r*180*60*60/pi);
      s = n%60; n /= 60;
      m = n%60; n /= 60;
      d = n;
    }
    

    or (this is probably more efficient), do as your solution, but check for seconds overflow and adjust accordingly:

    void r2dms(float r, int &d, int &m, int &s)
    {
      r *= 180/pi;
      d = floor(r);
      r = (r-d)*60;
      m = floor(r);
      r = (r-m)*60;
      s = round(r);
      if (s == 60) {
        s = 0; m++;
        if (m == 60) {
          d = 0; d++;
        }
      }
    }
    

    One slight residual doubt about this is if the minutes can overflow as well: if x < 1, then is k*x < k? – clearly mathematically true, but maybe the rounding of the multiplication can make the result be exactly k. Seems to work for 60 (60*nextafter(1,0) < 60 anyway) but can't see how to prove it.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: