Angles (geometric), normalization and conversion
You are encouraged to solve this task according to the task description, using any language you may know.
This task is about the normalization and/or conversion of (geometric) angles using some common scales.
The angular scales that will be used in this task are:
- degree
- gradian
- mil
- radian
- Definitions
The angular scales used or referenced here:
- turn is a full turn or 360 degrees, also shown as 360º
- degree is 1/360 of a turn
- gradian is 1/400 of a turn
- mil is 1/6400 of a turn
- radian is 1/2 of a turn (or 0.5/ of a turn)
Or, to put it another way, for a full circle:
- there are 360 degrees
- there are 400 gradians
- there are 6,400 mils
- there are 2 radians (roughly equal to 6.283+)
A mil is approximately equal to a milliradian (which is 1/1000 of a radian).
There is another definition of a mil which is 1/1000 of a radian ─── this definition won't be used in this Rosetta Code task.
Turns are sometimes known or shown as:
- turn(s)
- 360 degrees
- unit circle
- a (full) circle
Degrees are sometimes known or shown as:
- degree(s)
- deg
- º (a symbol)
- ° (a symbol)
Gradians are sometimes known or shown as:
- gradian(s)
- grad(s)
- grade(s)
- gon(s)
- metric degree(s)
Mils are sometimes known or shown as:
- mil(s)
- NATO mil(s)
Radians are sometimes known or shown as:
- radian(s)
- rad(s)
- Notes
In continental Europe, the French term centigrade was used for 1/100 of a grad (grade); this was one reason for the adoption of the term Celsius to replace centigrade as the name of a temperature scale.
Gradians were commonly used in civil engineering.
Mils were normally used for artillery (elevations of the gun barrel for ranging).
- Positive and negative angles
Although the definition of the measurement of an angle doesn't support the concept of a negative angle, it's frequently useful to impose a convention that allows positive and negative angular values to represent orientations and/or rotations in opposite directions relative to some reference. It is this reason that negative angles will keep their sign and not be normalized to positive angles.
- Normalization
Normalization (for this Rosetta Code task) will keep the same sign, but it will reduce the magnitude to less than a full circle; in other words, less than 360º.
Normalization shouldn't change -45º to 315º,
An angle of 0º, +0º, 0.000000, or -0º should be shown as 0º.
- Task
-
- write a function (or equivalent) to do the normalization for each scale
- Suggested names:
- d2d, g2g, m2m, and r2r
- write a function (or equivalent) to convert one scale to another
- Suggested names for comparison of different computer language function names:
- d2g, d2m, and d2r for degrees
- g2d, g2m, and g2r for gradians
- m2d, m2g, and m2r for mils
- r2d, r2g, and r2m for radians
- normalize all angles used (except for the "original" or "base" angle)
- show the angles in every scale and convert them to all other scales
- show all output here on this page
For the (above) conversions, use these dozen numbers (in the order shown):
- -2 -1 0 1 2 6.2831853 16 57.2957795 359 399 6399 1000000
AWK
<lang AWK>
- syntax: GAWK -f ANGLES_(GEOMETRIC)_NORMALIZATION_AND_CONVERSION.AWK
- gawk starts showing discrepancies at test case number 7 when compared with C#
BEGIN {
pi = atan2(0,-1) data_leng = split("-2,-1,0,1,2,6.2831853,16,57.2957795,359,399,6399,1000000",data_arr,",") unit_leng = split("degree,gradian,mil,radian",unit_arr,",") printf("%-10s %-10s %-8s %-12s %-12s %-12s %-12s test#\n","angle","normalized","unit","degrees","gradians","mils","radians") for (a=1; a<=data_leng; a++) { angle = data_arr[a] arr["degree"] = normalize(angle,360) arr["gradian"] = normalize(angle,400) arr["mil"] = normalize(angle,6400) arr["radian"] = normalize(angle,pi*2) print("") # optional blank line between groupings for (b=1; b<=unit_leng; b++) { key1 = unit_arr[b] printf("%-10s %-10s %-8s",angle,arr[key1],unit_arr[b]) for (c=1; c<=unit_leng; c++) { key2 = unit_arr[c] func_name = sprintf("%s2%s",key1,key2) printf(" %-12s",(key1 == key2) ? arr[key2] : @func_name(arr[key2])) } printf(" %d\n",a) } }
- normalize_usage_stats()
exit(0)
} function normalize(angle,n, a) {
a = angle profile_arr[a][n]["+"] = 0 profile_arr[a][n]["-"] = 0 while (angle <= -n) { angle += n ; profile_arr[a][n]["+"]++ } while (angle >= n) { angle -= n ; profile_arr[a][n]["-"]++ } return(angle)
} function normalize_usage_stats( a,b,c,n,total) {
print("") PROCINFO["sorted_in"] = "@ind_num_asc" for (a in profile_arr) { for (b in profile_arr[a]) { for (c in profile_arr[a][b]) { n = profile_arr[a][b][c] if (n == 0) { continue } printf("%10s %10s %1s %7d\n",a,b,c,n) total += n } } } printf("%31d total\n",total)
} function degree2gradian(angle) { return(angle * 10 / 9) } function degree2mil(angle) { return(angle * 160 / 9) } function degree2radian(angle) { return(angle * pi / 180) } function gradian2degree(angle) { return(angle * 9 / 10) } function gradian2mil(angle) { return(angle * 16) } function gradian2radian(angle) { return(angle * pi / 200) } function mil2degree(angle) { return(angle * 9 / 160) } function mil2gradian(angle) { return(angle / 16) } function mil2radian(angle) { return(angle * pi / 3200) } function radian2degree(angle) { return(angle * 180 / pi) } function radian2gradian(angle) { return(angle * 200 / pi) } function radian2mil(angle) { return(angle * 3200 / pi) } </lang>
- Output:
angle normalized unit degrees gradians mils radians test# -2 -2 degree -2 -2.22222 -35.5556 -0.0349066 1 -2 -2 gradian -1.8 -2 -32 -0.0314159 1 -2 -2 mil -0.1125 -0.125 -2 -0.0019635 1 -2 -2 radian -114.592 -127.324 -2037.18 -2 1 -1 -1 degree -1 -1.11111 -17.7778 -0.0174533 2 -1 -1 gradian -0.9 -1 -16 -0.015708 2 -1 -1 mil -0.05625 -0.0625 -1 -0.000981748 2 -1 -1 radian -57.2958 -63.662 -1018.59 -1 2 0 0 degree 0 0 0 0 3 0 0 gradian 0 0 0 0 3 0 0 mil 0 0 0 0 3 0 0 radian 0 0 0 0 3 1 1 degree 1 1.11111 17.7778 0.0174533 4 1 1 gradian 0.9 1 16 0.015708 4 1 1 mil 0.05625 0.0625 1 0.000981748 4 1 1 radian 57.2958 63.662 1018.59 1 4 2 2 degree 2 2.22222 35.5556 0.0349066 5 2 2 gradian 1.8 2 32 0.0314159 5 2 2 mil 0.1125 0.125 2 0.0019635 5 2 2 radian 114.592 127.324 2037.18 2 5 6.2831853 6.2831853 degree 6.2831853 6.98132 111.701 0.109662 6 6.2831853 6.2831853 gradian 5.65487 6.2831853 100.531 0.098696 6 6.2831853 6.2831853 mil 0.353429 0.392699 6.2831853 0.0061685 6 6.2831853 6.2831853 radian 360 400 6400 6.2831853 6 16 16 degree 16 17.7778 284.444 0.0599281 7 16 16 gradian 14.4 16 256 0.0539353 7 16 16 mil 0.9 1 16 0.00337096 7 16 3.43363 radian 916.732 1018.59 16297.5 3.43363 7 57.2957795 57.2957795 degree 57.2957795 63.662 1018.59 0.0130396 8 57.2957795 57.2957795 gradian 51.5662 57.2957795 916.732 0.0117356 8 57.2957795 57.2957795 mil 3.22289 3.58099 57.2957795 0.000733475 8 57.2957795 0.747112 radian 3282.81 3647.56 58361 0.747112 8 359 359 degree 359 398.889 6382.22 0.0149826 9 359 359 gradian 323.1 359 5744 0.0134843 9 359 359 mil 20.1938 22.4375 359 0.000842769 9 359 0.858437 radian 20569.2 22854.6 365674 0.858437 9 399 39 degree 39 443.333 7093.33 0.0551406 10 399 399 gradian 35.1 399 6384 0.0496266 10 399 399 mil 2.19375 24.9375 399 0.00310166 10 399 3.15933 radian 2234.54 25401.1 406418 3.15933 10 6399 279 degree 279 443.333 113760 0.0474268 11 6399 399 gradian 251.1 399 102384 0.0426841 11 6399 6399 mil 15.6937 24.9375 6399 0.00266776 11 6399 2.71736 radian 15985.5 25401.1 6.51797e+006 2.71736 11 1000000 280 degree 280 0 28444.4 0.103422 12 1000000 0 gradian 252 0 25600 0.0930795 12 1000000 1600 mil 15.75 0 1600 0.00581747 12 1000000 5.92562 radian 16042.8 0 1.62975e+006 5.92562 12
C
<lang c>#define PI 3.141592653589793
- define TWO_PI 6.283185307179586
double normalize2deg(double a) {
while (a < 0) a += 360; while (a >= 360) a -= 360; return a;
} double normalize2grad(double a) {
while (a < 0) a += 400; while (a >= 400) a -= 400; return a;
} double normalize2mil(double a) {
while (a < 0) a += 6400; while (a >= 6400) a -= 6400; return a;
} double normalize2rad(double a) {
while (a < 0) a += TWO_PI; while (a >= TWO_PI) a -= TWO_PI; return a;
}
double deg2grad(double a) {return a * 10 / 9;} double deg2mil(double a) {return a * 160 / 9;} double deg2rad(double a) {return a * PI / 180;}
double grad2deg(double a) {return a * 9 / 10;} double grad2mil(double a) {return a * 16;} double grad2rad(double a) {return a * PI / 200;}
double mil2deg(double a) {return a * 9 / 160;} double mil2grad(double a) {return a / 16;} double mil2rad(double a) {return a * PI / 3200;}
double rad2deg(double a) {return a * 180 / PI;} double rad2grad(double a) {return a * 200 / PI;} double rad2mil(double a) {return a * 3200 / PI;}</lang>
C#
<lang csharp>using System;
public static class Angles {
public static void Main() => Print(-2, -1, 0, 1, 2, 6.2831853, 16, 57.2957795, 359, 6399, 1_000_000);
public static void Print(params double[] angles) { string[] names = { "Degrees", "Gradians", "Mils", "Radians" }; Func<double, double> rnd = a => Math.Round(a, 4); Func<double, double>[] normal = { NormalizeDeg, NormalizeGrad, NormalizeMil, NormalizeRad };
Func<double, double>[,] convert = { { a => a, DegToGrad, DegToMil, DegToRad }, { GradToDeg, a => a, GradToMil, GradToRad }, { MilToDeg, MilToGrad, a => a, MilToRad }, { RadToDeg, RadToGrad, RadToMil, a => a } };
Console.WriteLine($@"{"Angle",-12}{"Normalized",-12}{"Unit",-12}{ "Degrees",-12}{"Gradians",-12}{"Mils",-12}{"Radians",-12}");
foreach (double angle in angles) { for (int i = 0; i < 4; i++) { double nAngle = normal[i](angle);
Console.WriteLine($@"{ rnd(angle),-12}{ rnd(nAngle),-12}{ names[i],-12}{ rnd(convert[i, 0](nAngle)),-12}{ rnd(convert[i, 1](nAngle)),-12}{ rnd(convert[i, 2](nAngle)),-12}{ rnd(convert[i, 3](nAngle)),-12}"); } } }
public static double NormalizeDeg(double angle) => Normalize(angle, 360); public static double NormalizeGrad(double angle) => Normalize(angle, 400); public static double NormalizeMil(double angle) => Normalize(angle, 6400); public static double NormalizeRad(double angle) => Normalize(angle, 2 * Math.PI);
private static double Normalize(double angle, double N) { while (angle <= -N) angle += N; while (angle >= N) angle -= N; return angle; }
public static double DegToGrad(double angle) => angle * 10 / 9; public static double DegToMil(double angle) => angle * 160 / 9; public static double DegToRad(double angle) => angle * Math.PI / 180; public static double GradToDeg(double angle) => angle * 9 / 10; public static double GradToMil(double angle) => angle * 16; public static double GradToRad(double angle) => angle * Math.PI / 200; public static double MilToDeg(double angle) => angle * 9 / 160; public static double MilToGrad(double angle) => angle / 16; public static double MilToRad(double angle) => angle * Math.PI / 3200; public static double RadToDeg(double angle) => angle * 180 / Math.PI; public static double RadToGrad(double angle) => angle * 200 / Math.PI; public static double RadToMil(double angle) => angle * 3200 / Math.PI;
}</lang>
- Output:
Angle Normalized Unit Degrees Gradians Mils Radians -2 -2 Degrees -2 -2.2222 -35.5556 -0.0349 -2 -2 Gradiens -1.8 -2 -32 -0.0314 -2 -2 Mils -0.1125 -0.125 -2 -0.002 -2 -2 Radians -114.5916 -127.324 -2037.1833 -2 -1 -1 Degrees -1 -1.1111 -17.7778 -0.0175 -1 -1 Gradiens -0.9 -1 -16 -0.0157 -1 -1 Mils -0.0562 -0.0625 -1 -0.001 -1 -1 Radians -57.2958 -63.662 -1018.5916 -1 0 0 Degrees 0 0 0 0 0 0 Gradiens 0 0 0 0 0 0 Mils 0 0 0 0 0 0 Radians 0 0 0 0 1 1 Degrees 1 1.1111 17.7778 0.0175 1 1 Gradiens 0.9 1 16 0.0157 1 1 Mils 0.0562 0.0625 1 0.001 1 1 Radians 57.2958 63.662 1018.5916 1 2 2 Degrees 2 2.2222 35.5556 0.0349 2 2 Gradiens 1.8 2 32 0.0314 2 2 Mils 0.1125 0.125 2 0.002 2 2 Radians 114.5916 127.324 2037.1833 2 6.2832 6.2832 Degrees 6.2832 6.9813 111.7011 0.1097 6.2832 6.2832 Gradiens 5.6549 6.2832 100.531 0.0987 6.2832 6.2832 Mils 0.3534 0.3927 6.2832 0.0062 6.2832 6.2832 Radians 360 400 6400 6.2832 16 16 Degrees 16 17.7778 284.4444 0.2793 16 16 Gradiens 14.4 16 256 0.2513 16 16 Mils 0.9 1 16 0.0157 16 3.4336 Radians 196.7325 218.5916 3497.4662 3.4336 57.2958 57.2958 Degrees 57.2958 63.662 1018.5916 1 57.2958 57.2958 Gradiens 51.5662 57.2958 916.7325 0.9 57.2958 57.2958 Mils 3.2229 3.581 57.2958 0.0562 57.2958 0.7471 Radians 42.8063 47.5626 761.0018 0.7471 359 359 Degrees 359 398.8889 6382.2222 6.2657 359 359 Gradiens 323.1 359 5744 5.6392 359 359 Mils 20.1938 22.4375 359 0.3524 359 0.8584 Radians 49.1848 54.6498 874.3972 0.8584 6399 279 Degrees 279 310 4960 4.8695 6399 399 Gradiens 359.1 399 6384 6.2675 6399 6399 Mils 359.9438 399.9375 6399 6.2822 6399 2.7174 Radians 155.6931 172.9923 2767.8774 2.7174 1000000 280 Degrees 280 311.1111 4977.7778 4.8869 1000000 0 Gradiens 0 0 0 0 1000000 1600 Mils 90 100 1600 1.5708 1000000 5.9256 Radians 339.5132 377.2368 6035.7895 5.9256
C++
<lang cpp>#include <functional>
- include <iostream>
- include <iomanip>
- include <math.h>
- include <sstream>
- include <vector>
- include <boost/algorithm/string.hpp>
template<typename T> T normalize(T a, double b) { return std::fmod(a, b); }
inline double d2d(double a) { return normalize<double>(a, 360); } inline double g2g(double a) { return normalize<double>(a, 400); } inline double m2m(double a) { return normalize<double>(a, 6400); } inline double r2r(double a) { return normalize<double>(a, 2*M_PI); }
double d2g(double a) { return g2g(a * 10 / 9); } double d2m(double a) { return m2m(a * 160 / 9); } double d2r(double a) { return r2r(a * M_PI / 180); } double g2d(double a) { return d2d(a * 9 / 10); } double g2m(double a) { return m2m(a * 16); } double g2r(double a) { return r2r(a * M_PI / 200); } double m2d(double a) { return d2d(a * 9 / 160); } double m2g(double a) { return g2g(a / 16); } double m2r(double a) { return r2r(a * M_PI / 3200); } double r2d(double a) { return d2d(a * 180 / M_PI); } double r2g(double a) { return g2g(a * 200 / M_PI); } double r2m(double a) { return m2m(a * 3200 / M_PI); }
void print(const std::vector<double> &values, const char *s, std::function<double(double)> f) {
using namespace std; ostringstream out; out << " ┌───────────────────┐\n"; out << " │ " << setw(17) << s << " │\n"; out << "┌─────────────────┼───────────────────┤\n"; for (double i : values) out << "│ " << setw(15) << fixed << i << defaultfloat << " │ " << setw(17) << fixed << f(i) << defaultfloat << " │\n"; out << "└─────────────────┴───────────────────┘\n"; auto str = out.str(); boost::algorithm::replace_all(str, ".000000", " "); cout << str;
}
int main() {
std::vector<double> values = { -2, -1, 0, 1, 2, 6.2831853, 16, 57.2957795, 359, 399, 6399, 1000000 }; print(values, "normalized (deg)", d2d); print(values, "normalized (grad)", g2g); print(values, "normalized (mil)", m2m); print(values, "normalized (rad)", r2r);
print(values, "deg -> grad ", d2g); print(values, "deg -> mil ", d2m); print(values, "deg -> rad ", d2r);
print(values, "grad -> deg ", g2d); print(values, "grad -> mil ", g2m); print(values, "grad -> rad ", g2r);
print(values, "mil -> deg ", m2d); print(values, "mil -> grad ", m2g); print(values, "mil -> rad ", m2r);
print(values, "rad -> deg ", r2d); print(values, "rad -> grad ", r2g); print(values, "rad -> mil ", r2m);
return 0;
}</lang>
- Output:
┌───────────────────┐ │ normalized (deg) │ ┌─────────────────┼───────────────────┤ │ -2 │ -2 │ │ -1 │ -1 │ │ 0 │ 0 │ │ 1 │ 1 │ │ 2 │ 2 │ │ 6.283185 │ 6.283185 │ │ 16 │ 16 │ │ 57.295780 │ 57.295780 │ │ 359 │ 359 │ │ 399 │ 39 │ │ 6399 │ 279 │ │ 1000000 │ 280 │ └─────────────────┴───────────────────┘ ... ┌───────────────────┐ │ rad -> mil │ ┌─────────────────┼───────────────────┤ │ -2 │ -2037.183272 │ │ -1 │ -1018.591636 │ │ 0 │ 0 │ │ 1 │ 1018.591636 │ │ 2 │ 2037.183272 │ │ 6.283185 │ 6399.999993 │ │ 16 │ 3497.466173 │ │ 57.295780 │ 761.001765 │ │ 359 │ 874.397248 │ │ 399 │ 3218.062679 │ │ 6399 │ 2767.877408 │ │ 1000000 │ 6035.788130 │ └─────────────────┴───────────────────┘
Common Lisp
Usage: (angles angle(s)) or (angles) for auto-test. VAL* is unnormalized. <lang lisp>(defun DegToDeg (a) (rem a 360)) (defun GradToGrad (a) (rem a 400)) (defun MilToMil (a) (rem a 6400)) (defun RadToRad (a) (rem a (* 2 pi)))
(defun DegToGrad (a) (GradToGrad (* (/ a 360) 400))) (defun DegToRad (a) (RadToRad (* (/ a 360) (* 2 pi)))) (defun DegToMil (a) (MilToMil (* (/ a 360) 6400)))
(defun GradToDeg (a) (DegToDeg (* (/ a 400) 360))) (defun GradToRad (a) (RadToRad (* (/ a 400) (* 2 pi)))) (defun GradToMil (a) (MilToMil (* (/ a 400) 6400)))
(defun MilToDeg (a) (DegToDeg (* (/ a 6400) 360))) (defun MilToGrad (a) (GradToGrad (* (/ a 6400) 400))) (defun MilToRad (a) (RadToRad (* (/ a 6400) (* 2 pi))))
(defun RadToDeg (a) (DegToDeg (* (/ a (* 2 pi)) 360))) (defun RadToGrad (a) (GradToGrad (* (/ a (* 2 pi)) 400))) (defun RadToMil (a) (MilToMil (* (/ a (* 2 pi)) 6400)))
(defun angles (&rest angles)
(if (not angles) (setf angles '(-2 -1 0 1 2 6.2831853 16 57.2957795 359 399 6399 1000000))) (dolist (a angles) (format t "UNIT ~15@a ~15@a ~15@a ~15@a ~15@a~%" "VAL*" "DEG" "GRAD" "MIL" "RAD") (format t "Deg | ~15f | ~15f | ~15f | ~15f | ~15f~%" a (DegToDeg a) (DegToGrad a) (DegToMil a) (DegToRad a)) (format t "Grad | ~15f | ~15f | ~15f | ~15f | ~15f~%" a (GradToDeg a) (GradToGrad a) (GradToMil a) (GradToRad a)) (format t "Mil | ~15f | ~15f | ~15f | ~15f | ~15f~%" a (MilToDeg a) (MilToGrad a) (MilToMil a) (MilToRad a)) (format t "Rad | ~15f | ~15f | ~15f | ~15f | ~15f~%~%" a (RadToDeg a) (RadToGrad a) (RadToMil a) (RadToRad a))))</lang>
- Output:
[CLISP]> (angles) UNIT VAL* DEG GRAD MIL RAD Deg | -2.0 | -2.0 | -2.2222223 | -35.555557 | -.0349065850399 Grad | -2.0 | -1.8 | -2.0 | -32.0 | -.0314159265359 Mil | -2.0 | -0.1125 | -0.125 | -2.0 | -.0019634954085 Rad | -2.0 | -114.5915590262 | -127.3239544735 | -2037.183271576 | -2.0 UNIT VAL* DEG GRAD MIL RAD Deg | -1.0 | -1.0 | -1.1111112 | -17.777779 | -.0174532925199 Grad | -1.0 | -0.9 | -1.0 | -16.0 | -.0157079632679 Mil | -1.0 | -0.05625 | -0.0625 | -1.0 | -.0009817477042 Rad | -1.0 | -57.29577951308 | -63.66197723676 | -1018.591635788 | -1.0 UNIT VAL* DEG GRAD MIL RAD Deg | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 Grad | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 Mil | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 Rad | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 UNIT VAL* DEG GRAD MIL RAD Deg | 1.0 | 1.0 | 1.1111112 | 17.777779 | .01745329251994 Grad | 1.0 | 0.9 | 1.0 | 16.0 | .01570796326795 Mil | 1.0 | 0.05625 | 0.0625 | 1.0 | .00098174770425 Rad | 1.0 | 57.295779513082 | 63.661977236758 | 1018.5916357881 | 1.0 UNIT VAL* DEG GRAD MIL RAD Deg | 2.0 | 2.0 | 2.2222223 | 35.555557 | .03490658503989 Grad | 2.0 | 1.8 | 2.0 | 32.0 | 0.0314159265359 Mil | 2.0 | 0.1125 | 0.125 | 2.0 | .00196349540849 Rad | 2.0 | 114.59155902616 | 127.32395447352 | 2037.1832715763 | 2.0 UNIT VAL* DEG GRAD MIL RAD Deg | 6.2831855 | 6.2831855 | 6.981317 | 111.70107 | 0.10966227 Grad | 6.2831855 | 5.654867 | 6.2831855 | 100.53097 | 0.098696046 Mil | 6.2831855 | 0.3534292 | 0.3926991 | 6.2831855 | 0.006168503 Rad | 6.2831855 | 0.0 | 0.0 | 0.0 | 0.0 UNIT VAL* DEG GRAD MIL RAD Deg | 16.0 | 16.0 | 17.777779 | 284.44446 | .27925268031909 Grad | 16.0 | 14.4 | 16.0 | 256.0 | .25132741228718 Mil | 16.0 | 0.9 | 1.0 | 16.0 | .01570796326795 Rad | 16.0 | 196.73247220932 | 218.59163578813 | 3497.4661726101 | 3.4336293856408 UNIT VAL* DEG GRAD MIL RAD Deg | 57.29578 | 57.295784 | 63.66198 | 1018.5917 | 0.99999994 Grad | 57.29578 | 51.566204 | 57.29578 | 916.7325 | 0.90000004 Mil | 57.29578 | 3.2228878 | 3.5809863 | 57.29578 | 0.056250002 Rad | 57.29578 | 42.80651 | 47.56279 | 761.00464 | 0.74711454 UNIT VAL* DEG GRAD MIL RAD Deg | 359.0 | 359.0 | 398.8889 | 6382.222 | 6.2657320146596 Grad | 359.0 | 323.1 | 359.0 | 5744.0 | 5.6391588131937 Mil | 359.0 | 20.19375 | 22.4375 | 359.0 | 0.3524474258246 Rad | 359.0 | 49.184845196553 | 54.64982799617 | 874.39724793872 | .85843749076357 UNIT VAL* DEG GRAD MIL RAD Deg | 399.0 | 39.0 | 43.333332 | 693.3333 | .68067840827779 Grad | 399.0 | 359.1 | 399.0 | 6384.0 | 6.2674773439116 Mil | 399.0 | 22.44375 | 24.9375 | 399.0 | .39171733399448 Rad | 399.0 | 181.01602571985 | 201.1289174665 | 3218.0626794639 | 3.1593256476861 UNIT VAL* DEG GRAD MIL RAD Deg | 6399.0 | 279.0 | 310.0 | 4960.0 | 4.8694686130642 Grad | 6399.0 | 359.1 | 399.0 | 6384.0 | 6.2674773439116 Mil | 6399.0 | 359.94376 | 399.9375 | 6399.0 | 6.2822035594753 Rad | 6399.0 | 155.69310421377 | 172.9923380153 | 2767.8774082448 | 2.717357291181 UNIT VAL* DEG GRAD MIL RAD Deg | 1000000.0 | 280.0 | 311.1111 | 4977.778 | 4.8869219055841 Grad | 1000000.0 | 0.0 | 0.0 | 0.0 | 0.0 Mil | 1000000.0 | 90.0 | 100.0 | 1600.0 | 1.5707963267949 Rad | 1000000.0 | 339.51308232088 | 377.23675813431 | 6035.7881301489 | 5.9256211400939
Delphi
<lang Delphi> program normalization_and_conversion;
{$APPTYPE CONSOLE}
uses
System.SysUtils, System.Math;
function d2d(d: double): double; begin
result := FMod(d, 360);
end;
function g2g(g: double): double; begin
result := FMod(g, 400);
end;
function m2m(m: double): double; begin
result := FMod(m, 6400);
end;
function r2r(r: double): double; begin
result := FMod(r, 2 * Pi);
end;
function d2g(d: double): double; begin
result := d2d(d) * 400 / 360;
end;
function d2m(d: double): double; begin
result := d2d(d) * 6400 / 360;
end;
function d2r(d: double): double; begin
result := d2d(d) * Pi / 180;
end;
function g2d(g: double): double; begin
result := g2g(g) * 360 / 400;
end;
function g2m(g: double): double; begin
result := g2g(g) * 6400 / 400;
end;
function g2r(g: double): double; begin
result := g2g(g) * Pi / 200;
end;
function m2d(m: double): double; begin
result := m2m(m) * 360 / 6400;
end;
function m2g(m: double): double; begin
result := m2m(m) * 400 / 6400;
end;
function m2r(m: double): double; begin
result := m2m(m) * Pi / 3200;
end;
function r2d(r: double): double; begin
result := r2r(r) * 180 / Pi;
end;
function r2g(r: double): double; begin
result := r2r(r) * 200 / Pi;
end;
function r2m(r: double): double; begin
result := r2r(r) * 3200 / Pi;
end;
function s(f: double): string; begin
var wf := FloatToStrF(f, ffGeneral, 16, 64).Split([FormatSettings.DecimalSeparator], TStringSplitOptions.ExcludeEmpty); if Length(wf) = 1 then exit(format('%7s ', [wf[0]])); var le := length(wf[1]); if le > 7 then le := 7; Result := format('%7s.%-7s', [wf[0], copy(wf[1], 0, le)]);
end;
begin
var angles: TArray<Double> := [-2, -1, 0, 1, 2, 6.2831853, 16, 57.2957795, 359, 399, 6399, 1000000];
var ft := '%s %s %s %s %s';
writeln(format(ft, [' degrees ', 'normalized degs', ' gradians ', ' mils ', ' radians'])); for var a in angles do writeln(format(ft, [s(a), s(d2d(a)), s(d2g(a)), s(d2m(a)), s(d2r(a))]));
writeln(format(ft, [#10' gradians ', 'normalized grds', ' degrees ', ' mils ', ' radians']));
for var a in angles do writeln(format(ft, [s(a), s(g2g(a)), s(g2d(a)), s(g2m(a)), s(g2r(a))]));
writeln(format(ft, [#10' mils ', 'normalized mils', ' degrees ', ' gradians ', ' radians'])); for var a in angles do writeln(format(ft, [s(a), s(m2m(a)), s(m2d(a)), s(m2g(a)), s(m2r(a))]));
writeln(format(ft, [#10' radians ', 'normalized rads', ' degrees ', ' gradians ', ' mils '])); for var a in angles do writeln(format(ft, [s(a), s(r2r(a)), s(r2d(a)), s(r2g(a)), s(r2m(a))])); readln;
end.</lang>
Factor
Radians and degrees are already defined in the units.si
vocabulary. Gradiens and mils are defined in terms of degrees. Conversions from unit to unit are handled by inverse functions; [undo]
knows how to deconstruct units in terms of other units. (Assuming, of course, new units are defined entirely with words that have inverses.)
<lang factor>USING: accessors combinators formatting inverse kernel math
math.constants quotations qw sequences units.si ;
IN: rosetta-code.angles
ALIAS: degrees arc-deg
- gradiens ( n -- d ) 9/10 * degrees ;
- mils ( n -- d ) 9/160 * degrees ;
- normalize ( d -- d' ) [ 2 pi * mod ] change-value ;
CONSTANT: units { degrees gradiens mils radians }
- .row ( angle unit -- )
2dup "%-12u%-12s" printf ( x -- x ) execute-effect normalize units [ 1quotation [undo] call( x -- x ) ] with map "%-12.4f%-12.4f%-12.4f%-12.4f\n" vprintf ;
- .header ( -- )
qw{ angle unit } units append "%-12s%-12s%-12s%-12s%-12s%-12s\n" vprintf ;
- angles ( -- )
.header { -2 -1 0 1 2 6.2831853 16 57.2957795 359 399 6399 1000000 } units [ .row ] cartesian-each ;
MAIN: angles</lang>
- Output:
angle unit degrees gradiens mils radians -2 degrees -2.0000 -2.2222 -35.5556 -0.0349 -2 gradiens -1.8000 -2.0000 -32.0000 -0.0314 -2 mils -0.1125 -0.1250 -2.0000 -0.0020 -2 radians -114.5916 -127.3240 -2037.1833 -2.0000 -1 degrees -1.0000 -1.1111 -17.7778 -0.0175 -1 gradiens -0.9000 -1.0000 -16.0000 -0.0157 -1 mils -0.0563 -0.0625 -1.0000 -0.0010 -1 radians -57.2958 -63.6620 -1018.5916 -1.0000 0 degrees 0.0000 0.0000 0.0000 0.0000 0 gradiens 0.0000 0.0000 0.0000 0.0000 0 mils 0.0000 0.0000 0.0000 0.0000 0 radians 0.0000 0.0000 0.0000 0.0000 1 degrees 1.0000 1.1111 17.7778 0.0175 1 gradiens 0.9000 1.0000 16.0000 0.0157 1 mils 0.0563 0.0625 1.0000 0.0010 1 radians 57.2958 63.6620 1018.5916 1.0000 2 degrees 2.0000 2.2222 35.5556 0.0349 2 gradiens 1.8000 2.0000 32.0000 0.0314 2 mils 0.1125 0.1250 2.0000 0.0020 2 radians 114.5916 127.3240 2037.1833 2.0000 6.2831853 degrees 6.2832 6.9813 111.7011 0.1097 6.2831853 gradiens 5.6549 6.2832 100.5310 0.0987 6.2831853 mils 0.3534 0.3927 6.2832 0.0062 6.2831853 radians 360.0000 400.0000 6400.0000 6.2832 16 degrees 16.0000 17.7778 284.4444 0.2793 16 gradiens 14.4000 16.0000 256.0000 0.2513 16 mils 0.9000 1.0000 16.0000 0.0157 16 radians 196.7325 218.5916 3497.4662 3.4336 57.2957795 degrees 57.2958 63.6620 1018.5916 1.0000 57.2957795 gradiens 51.5662 57.2958 916.7325 0.9000 57.2957795 mils 3.2229 3.5810 57.2958 0.0562 57.2957795 radians 42.8063 47.5626 761.0018 0.7471 359 degrees 359.0000 398.8889 6382.2222 6.2657 359 gradiens 323.1000 359.0000 5744.0000 5.6392 359 mils 20.1938 22.4375 359.0000 0.3524 359 radians 49.1848 54.6498 874.3972 0.8584 399 degrees 39.0000 43.3333 693.3333 0.6807 399 gradiens 359.1000 399.0000 6384.0000 6.2675 399 mils 22.4438 24.9375 399.0000 0.3917 399 radians 181.0160 201.1289 3218.0627 3.1593 6399 degrees 279.0000 310.0000 4960.0000 4.8695 6399 gradiens 359.1000 399.0000 6384.0000 6.2675 6399 mils 359.9438 399.9375 6399.0000 6.2822 6399 radians 155.6931 172.9923 2767.8774 2.7174 1000000 degrees 280.0000 311.1111 4977.7778 4.8869 1000000 gradiens 0.0000 0.0000 0.0000 0.0000 1000000 mils 90.0000 100.0000 1600.0000 1.5708 1000000 radians 339.5131 377.2368 6035.7881 5.9256
FreeBASIC
Provides a single function that does the normalising and converting. Supports D, G, M, R, T for degrees, gradians, mils, radians, and turns respectively. <lang freebasic>#define PI 3.1415926535897932384626433832795028842
- define INVALID -99999
function clamp( byval n as double, lo as double, hi as double ) as double
while n <= lo n += (hi - lo)/2 wend while n >= hi n += (lo - hi)/2 wend return n
end function
function anglenc( byval angle as double, byval source as string, byval targ as string ) as double
source = ucase(source) targ = ucase(targ) select case source case "D": angle = clamp(angle, -360, 360) select case targ case "D": return angle case "G": return angle*10/9 case "M": return angle*160/9 case "R": return angle*PI/180 case "T": return angle/360 case else return INVALID end select case "G": angle = clamp(angle, -400, 400) select case targ case "D": return angle*9/10 case "G": return angle case "M": return angle*16 case "R": return angle*PI/200 case "T": return angle/400 case else return INVALID end select case "M": angle = clamp(angle, -6400, 6400) select case targ case "D": return angle*9/160 case "G": return angle/16 case "M": return angle case "R": return angle*PI/3200 case "T": return angle/6400 case else return INVALID end select case "R": angle = clamp(angle, -2*PI, 2*PI) select case targ case "D": return angle*180/PI case "G": return angle*200/PI case "M": return angle*3200/PI case "R": return angle case "T": return angle/(2*PI) case else return INVALID end select case "T": angle = clamp(angle, -1, 1) select case targ case "D": return angle*360 case "G": return angle*400 case "M": return angle*6400 case "R": return angle*2*PI case "T": return angle case else return INVALID end select case else: return INVALID end select
end function
function clip( st as string, num as uinteger ) as string
if len(st)<num then return st return left(st, num)
end function
dim as string scales = "DGMRT", source, targ dim as double angles(12) = {-2, -1, 0, 1, 2, 6.2831853, 16, 57.2957795, 359, 399, 6399, 1000000} print "Angle Normalised Unit | D G M R T" for k as ubyte = 0 to 11
for i as ubyte = 1 to 5 source = mid(scales,i,1) print angles(k), clip(str(anglenc(angles(k), source, source )), 10), source, "|", for j as ubyte = 1 to 5 targ = mid(scales, j, 1) print clip(str(anglenc(angles(k), source, targ )), 10), next j print next i
next k </lang>
- Output:
Angle Normalised Unit | D G M R T -2 -2 D | -2 -2.2222222 -35.555555 -0.0349065 -0.0055555 -2 -2 G | -1.8 -2 -32 -0.0314159 -0.005 -2 -2 M | -0.1125 -0.125 -2 -0.0019634 -0.0003125 -2 -2 R | -114.59155 -127.32395 -2037.1832 -2 -0.3183098 -2 0 T | 0 0 0 0 0 -1 -1 D | -1 -1.1111111 -17.777777 -0.0174532 -0.0027777 -1 -1 G | -0.9 -1 -16 -0.0157079 -0.0025 -1 -1 M | -0.05625 -0.0625 -1 -0.0009817 -0.0001562 -1 -1 R | -57.295779 -63.661977 -1018.5916 -1 -0.1591549 -1 0 T | 0 0 0 0 0 0 0 D | 0 0 0 0 0 0 0 G | 0 0 0 0 0 0 0 M | 0 0 0 0 0 0 0 R | 0 0 0 0 0 0 0 T | 0 0 0 0 0 1 1 D | 1 1.11111111 17.7777777 0.01745329 0.00277777 1 1 G | 0.9 1 16 0.01570796 0.0025 1 1 M | 0.05625 0.0625 1 0.00098174 0.00015625 1 1 R | 57.2957795 63.6619772 1018.59163 1 0.15915494 1 0 T | 0 0 0 0 0 2 2 D | 2 2.22222222 35.5555555 0.03490658 0.00555555 2 2 G | 1.8 2 32 0.03141592 0.005 2 2 M | 0.1125 0.125 2 0.00196349 0.0003125 2 2 R | 114.591559 127.323954 2037.18327 2 0.31830988 2 0 T | 0 0 0 0 0 6.2831853 6.2831853 D | 6.2831853 6.98131700 111.701072 0.10966227 0.01745329 6.2831853 6.2831853 G | 5.65486677 6.2831853 100.530964 0.09869604 0.01570796 6.2831853 6.2831853 M | 0.35342917 0.39269908 6.2831853 0.00616850 0.00098174 6.2831853 6.2831853 R | 359.999999 399.999999 6399.99999 6.2831853 0.99999999 6.2831853 0.28318530 T | 101.946708 113.274120 1812.38592 1.77930571 0.28318530 16 16 D | 16 17.7777777 284.444444 0.27925268 0.04444444 16 16 G | 14.4 16 256 0.25132741 0.04 16 16 M | 0.9 1 16 0.01570796 0.0025 16 3.43362938 R | 196.732472 218.591635 3497.46617 3.43362938 0.54647908 16 0 T | 0 0 0 0 0 57.2957795 57.2957795 D | 57.2957795 63.6619772 1018.59163 0.99999999 0.15915494 57.2957795 57.2957795 G | 51.5662015 57.2957795 916.732472 0.89999999 0.14323944 57.2957795 57.2957795 M | 3.22288759 3.58098621 57.2957795 0.05624999 0.00895246 57.2957795 0.74711173 R | 42.8063492 47.5626102 761.001764 0.74711173 0.11890652 57.2957795 0.29577950 T | 106.480620 118.311800 1892.98880 1.85843740 0.29577950 359 359 D | 359 398.888888 6382.22222 6.26573201 0.99722222 359 359 G | 323.1 359 5744 5.63915881 0.8975 359 359 M | 20.19375 22.4375 359 0.35244742 0.05609375 359 0.85843749 R | 49.1848451 54.6498279 874.397247 0.85843749 0.13662456 359 0 T | 0 0 0 0 0 399 39 D | 39 43.3333333 693.333333 0.68067840 0.10833333 399 399 G | 359.1 399 6384 6.26747734 0.99750000 399 399 M | 22.44375 24.9375 399 0.39171733 0.06234375 399 3.15932564 R | 181.016025 201.128917 3218.06267 3.15932564 0.50282229 399 0 T | 0 0 0 0 0 6399 279 D | 279 310 4960 4.86946861 0.775 6399 399 G | 359.1 399 6384 6.26747734 0.99750000 6399 6399 M | 359.94375 399.9375 6399 6.28220355 0.99984375 6399 2.71735729 R | 155.693104 172.992338 2767.87740 2.71735729 0.43248084 6399 0 T | 0 0 0 0 0 1000000 280 D | 280 311.111111 4977.77777 4.88692190 0.77777777 1000000 0 G | 0 0 0 0 0 1000000 1600 M | 90 100 1600 1.57079632 0.25 1000000 5.92562252 R | 339.513161 377.236846 6035.78954 5.92562252 0.94309211 1000000 0 T | 0 0 0 0 0
Go
<lang go>package main
import (
"fmt" "math" "strconv" "strings"
)
func d2d(d float64) float64 { return math.Mod(d, 360) }
func g2g(g float64) float64 { return math.Mod(g, 400) }
func m2m(m float64) float64 { return math.Mod(m, 6400) }
func r2r(r float64) float64 { return math.Mod(r, 2*math.Pi) }
func d2g(d float64) float64 { return d2d(d) * 400 / 360 }
func d2m(d float64) float64 { return d2d(d) * 6400 / 360 }
func d2r(d float64) float64 { return d2d(d) * math.Pi / 180 }
func g2d(g float64) float64 { return g2g(g) * 360 / 400 }
func g2m(g float64) float64 { return g2g(g) * 6400 / 400 }
func g2r(g float64) float64 { return g2g(g) * math.Pi / 200 }
func m2d(m float64) float64 { return m2m(m) * 360 / 6400 }
func m2g(m float64) float64 { return m2m(m) * 400 / 6400 }
func m2r(m float64) float64 { return m2m(m) * math.Pi / 3200 }
func r2d(r float64) float64 { return r2r(r) * 180 / math.Pi }
func r2g(r float64) float64 { return r2r(r) * 200 / math.Pi }
func r2m(r float64) float64 { return r2r(r) * 3200 / math.Pi }
// Aligns number to decimal point assuming 7 characters before and after. func s(f float64) string {
wf := strings.Split(strconv.FormatFloat(f, 'g', 15, 64), ".") if len(wf) == 1 { return fmt.Sprintf("%7s ", wf[0]) } le := len(wf[1]) if le > 7 { le = 7 } return fmt.Sprintf("%7s.%-7s", wf[0], wf[1][:le])
}
func main() {
angles := []float64{-2, -1, 0, 1, 2, 6.2831853, 16, 57.2957795, 359, 399, 6399, 1000000} ft := "%s %s %s %s %s\n" fmt.Printf(ft, " degrees ", "normalized degs", " gradians ", " mils ", " radians") for _, a := range angles { fmt.Printf(ft, s(a), s(d2d(a)), s(d2g(a)), s(d2m(a)), s(d2r(a))) } fmt.Printf(ft, "\n gradians ", "normalized grds", " degrees ", " mils ", " radians") for _, a := range angles { fmt.Printf(ft, s(a), s(g2g(a)), s(g2d(a)), s(g2m(a)), s(g2r(a))) } fmt.Printf(ft, "\n mils ", "normalized mils", " degrees ", " gradians ", " radians") for _, a := range angles { fmt.Printf(ft, s(a), s(m2m(a)), s(m2d(a)), s(m2g(a)), s(m2r(a))) } fmt.Printf(ft, "\n radians ", "normalized rads", " degrees ", " gradians ", " mils ") for _, a := range angles { fmt.Printf(ft, s(a), s(r2r(a)), s(r2d(a)), s(r2g(a)), s(r2m(a))) }
}</lang>
- Output:
degrees normalized degs gradians mils radians -2 -2 -2.2222222 -35.5555555 -0.0349065 -1 -1 -1.1111111 -17.7777777 -0.0174532 0 0 0 0 0 1 1 1.1111111 17.7777777 0.0174532 2 2 2.2222222 35.5555555 0.0349065 6.2831853 6.2831853 6.981317 111.701072 0.1096622 16 16 17.7777777 284.4444444 0.2792526 57.2957795 57.2957795 63.6619772 1018.5916355 0.9999999 359 359 398.8888888 6382.2222222 6.2657320 399 39 43.3333333 693.3333333 0.6806784 6399 279 310 4960 4.8694686 1000000 280 311.1111111 4977.7777777 4.8869219 gradians normalized grds degrees mils radians -2 -2 -1.8 -32 -0.0314159 -1 -1 -0.9 -16 -0.0157079 0 0 0 0 0 1 1 0.9 16 0.0157079 2 2 1.8 32 0.0314159 6.2831853 6.2831853 5.6548667 100.5309648 0.0986960 16 16 14.4 256 0.2513274 57.2957795 57.2957795 51.5662015 916.732472 0.8999999 359 359 323.1 5744 5.6391588 399 399 359.1 6384 6.2674773 6399 399 359.1 6384 6.2674773 1000000 0 0 0 0 mils normalized mils degrees gradians radians -2 -2 -0.1125 -0.125 -0.0019634 -1 -1 -0.05625 -0.0625 -0.0009817 0 0 0 0 0 1 1 0.05625 0.0625 0.0009817 2 2 0.1125 0.125 0.0019634 6.2831853 6.2831853 0.3534291 0.3926990 0.0061685 16 16 0.9 1 0.0157079 57.2957795 57.2957795 3.2228875 3.5809862 0.0562499 359 359 20.19375 22.4375 0.3524474 399 399 22.44375 24.9375 0.3917173 6399 6399 359.94375 399.9375 6.2822035 1000000 1600 90 100 1.5707963 radians normalized rads degrees gradians mils -2 -2 -114.5915590 -127.3239544 -2037.1832715 -1 -1 -57.2957795 -63.6619772 -1018.5916357 0 0 0 0 0 1 1 57.2957795 63.6619772 1018.5916357 2 2 114.5915590 127.3239544 2037.1832715 6.2831853 6.2831853 359.9999995 399.9999995 6399.9999926 16 3.4336293 196.7324722 218.5916357 3497.4661726 57.2957795 0.7471117 42.8063492 47.5626102 761.0017646 359 0.8584374 49.1848451 54.6498279 874.3972479 399 3.1593256 181.0160257 201.1289174 3218.0626794 6399 2.7173572 155.6931042 172.9923380 2767.8774082 1000000 5.9256211 339.5130823 377.2367581 6035.7881301
Groovy
This solution creates the concept of an angular quantity with subclasses for different units of measure. Rather than creating individual functions (d2d, r2m, etc.) this solution uses inheritance, polymorphism, and operator overloading to implement the conversions and comparisons in a relatively natural way for idiomatic Groovy. <lang groovy>import java.lang.reflect.Constructor
abstract class Angle implements Comparable<? extends Angle> {
double value
Angle(double value = 0) { this.value = normalize(value) }
abstract Number unitCircle() abstract String unitName()
Number normalize(double n) { n % this.unitCircle() }
def B asType(Class bClass){ if (bClass == this.class) return this bClass.getConstructor(Number.class).newInstance(0).tap { value = this.value * unitCircle() / this.unitCircle() } }
String toString() { "${String.format('%14.8f',value)}${this.unitName()}" }
int hashCode() { value.hashCode() + 17 * unit().hashCode() }
int compareTo(Angle that) { this.value * that.unitCircle() <=> that.value * this.unitCircle() }
boolean equals(that) { this.is(that) ? true : that instanceof Angle ? (this <=> that) == 0 : that instanceof Number ? this.value == this.normalize(that) : super.equals(that) }
}
class Degrees extends Angle {
static final int UNIT_CIRCLE = 360 Number unitCircle() { UNIT_CIRCLE } static final String UNIT = "º " String unitName() { UNIT } Degrees(Number value = 0) { super(value) }
}
class Gradians extends Angle {
static final int UNIT_CIRCLE = 400 Number unitCircle() { UNIT_CIRCLE } static final String UNIT = " grad" String unitName() { UNIT } Gradians(Number value = 0) { super(value) }
}
class Mils extends Angle {
static final int UNIT_CIRCLE = 6400 Number unitCircle() { UNIT_CIRCLE } static final String UNIT = " mil " String unitName() { UNIT } Mils(Number value = 0) { super(value) }
}
class Radians extends Angle {
static final double UNIT_CIRCLE = Math.PI*2 Number unitCircle() { UNIT_CIRCLE } static final String UNIT = " rad " String unitName() { UNIT } Radians(Number value = 0) { super(value) }
}</lang>
This category class allows Angles to interoperate more easily with Numbers: <lang groovy>class AngleCategory {
static Degrees getDeg(Number n) { new Degrees(n) } static Gradians getGrad(Number n) { new Gradians(n) } static Mils getMil(Number n) { new Mils(n) } static Radians getRad(Number n) { new Radians(n) }
}</lang>
Test: <lang groovy>Number.metaClass.mixin AngleCategory
[ -2, -1, 0, 1, 2, 6.2831853, 16, 57.2957795, 359, 399, 6399, 1000000 ].each { rawAngle ->
println "\n raw angle normalized ------------------------------ conversions ------------------------------" [rawAngle.deg, rawAngle.grad, rawAngle.mil, rawAngle.rad].each { angle -> printf("%10s %20s %s %s %s %s\n", rawAngle.toString(), angle, angle as Degrees, angle as Gradians, angle as Mils, angle as Radians ) }
}
// some additional checks implied in the task statement // but not requested for solution demonstration assert 360.deg == 0.deg assert 90.deg == 100.grad assert Math.PI.rad == 3200.mil</lang>
- Output:
raw angle normalized ------------------------------ conversions ------------------------------ -2 -2.00000000º -2.00000000º -2.22222222 grad -35.55555556 mil -0.03490659 rad -2 -2.00000000 grad -1.80000000º -2.00000000 grad -32.00000000 mil -0.03141593 rad -2 -2.00000000 mil -0.11250000º -0.12500000 grad -2.00000000 mil -0.00196350 rad -2 -2.00000000 rad -114.59155903º -127.32395447 grad -2037.18327158 mil -2.00000000 rad raw angle normalized ------------------------------ conversions ------------------------------ -1 -1.00000000º -1.00000000º -1.11111111 grad -17.77777778 mil -0.01745329 rad -1 -1.00000000 grad -0.90000000º -1.00000000 grad -16.00000000 mil -0.01570796 rad -1 -1.00000000 mil -0.05625000º -0.06250000 grad -1.00000000 mil -0.00098175 rad -1 -1.00000000 rad -57.29577951º -63.66197724 grad -1018.59163579 mil -1.00000000 rad raw angle normalized ------------------------------ conversions ------------------------------ 0 0.00000000º 0.00000000º 0.00000000 grad 0.00000000 mil 0.00000000 rad 0 0.00000000 grad 0.00000000º 0.00000000 grad 0.00000000 mil 0.00000000 rad 0 0.00000000 mil 0.00000000º 0.00000000 grad 0.00000000 mil 0.00000000 rad 0 0.00000000 rad 0.00000000º 0.00000000 grad 0.00000000 mil 0.00000000 rad raw angle normalized ------------------------------ conversions ------------------------------ 1 1.00000000º 1.00000000º 1.11111111 grad 17.77777778 mil 0.01745329 rad 1 1.00000000 grad 0.90000000º 1.00000000 grad 16.00000000 mil 0.01570796 rad 1 1.00000000 mil 0.05625000º 0.06250000 grad 1.00000000 mil 0.00098175 rad 1 1.00000000 rad 57.29577951º 63.66197724 grad 1018.59163579 mil 1.00000000 rad raw angle normalized ------------------------------ conversions ------------------------------ 2 2.00000000º 2.00000000º 2.22222222 grad 35.55555556 mil 0.03490659 rad 2 2.00000000 grad 1.80000000º 2.00000000 grad 32.00000000 mil 0.03141593 rad 2 2.00000000 mil 0.11250000º 0.12500000 grad 2.00000000 mil 0.00196350 rad 2 2.00000000 rad 114.59155903º 127.32395447 grad 2037.18327158 mil 2.00000000 rad raw angle normalized ------------------------------ conversions ------------------------------ 6.2831853 6.28318530º 6.28318530º 6.98131700 grad 111.70107200 mil 0.10966227 rad 6.2831853 6.28318530 grad 5.65486677º 6.28318530 grad 100.53096480 mil 0.09869604 rad 6.2831853 6.28318530 mil 0.35342917º 0.39269908 grad 6.28318530 mil 0.00616850 rad 6.2831853 6.28318530 rad 359.99999959º 399.99999954 grad 6399.99999269 mil 6.28318530 rad raw angle normalized ------------------------------ conversions ------------------------------ 16 16.00000000º 16.00000000º 17.77777778 grad 284.44444444 mil 0.27925268 rad 16 16.00000000 grad 14.40000000º 16.00000000 grad 256.00000000 mil 0.25132741 rad 16 16.00000000 mil 0.90000000º 1.00000000 grad 16.00000000 mil 0.01570796 rad 16 3.43362939 rad 196.73247221º 218.59163579 grad 3497.46617261 mil 3.43362939 rad raw angle normalized ------------------------------ conversions ------------------------------ 57.2957795 57.29577950º 57.29577950º 63.66197722 grad 1018.59163556 mil 1.00000000 rad 57.2957795 57.29577950 grad 51.56620155º 57.29577950 grad 916.73247200 mil 0.90000000 rad 57.2957795 57.29577950 mil 3.22288760º 3.58098622 grad 57.29577950 mil 0.05625000 rad 57.2957795 0.74711174 rad 42.80634926º 47.56261029 grad 761.00176466 mil 0.74711174 rad raw angle normalized ------------------------------ conversions ------------------------------ 359 359.00000000º 359.00000000º 398.88888889 grad 6382.22222222 mil 6.26573201 rad 359 359.00000000 grad 323.10000000º 359.00000000 grad 5744.00000000 mil 5.63915881 rad 359 359.00000000 mil 20.19375000º 22.43750000 grad 359.00000000 mil 0.35244743 rad 359 0.85843749 rad 49.18484520º 54.64982800 grad 874.39724794 mil 0.85843749 rad raw angle normalized ------------------------------ conversions ------------------------------ 399 39.00000000º 39.00000000º 43.33333333 grad 693.33333333 mil 0.68067841 rad 399 399.00000000 grad 359.10000000º 399.00000000 grad 6384.00000000 mil 6.26747734 rad 399 399.00000000 mil 22.44375000º 24.93750000 grad 399.00000000 mil 0.39171733 rad 399 3.15932565 rad 181.01602572º 201.12891747 grad 3218.06267946 mil 3.15932565 rad raw angle normalized ------------------------------ conversions ------------------------------ 6399 279.00000000º 279.00000000º 310.00000000 grad 4960.00000000 mil 4.86946861 rad 6399 399.00000000 grad 359.10000000º 399.00000000 grad 6384.00000000 mil 6.26747734 rad 6399 6399.00000000 mil 359.94375000º 399.93750000 grad 6399.00000000 mil 6.28220356 rad 6399 2.71735729 rad 155.69310421º 172.99233802 grad 2767.87740825 mil 2.71735729 rad raw angle normalized ------------------------------ conversions ------------------------------ 1000000 280.00000000º 280.00000000º 311.11111111 grad 4977.77777778 mil 4.88692191 rad 1000000 0.00000000 grad 0.00000000º 0.00000000 grad 0.00000000 mil 0.00000000 rad 1000000 1600.00000000 mil 90.00000000º 100.00000000 grad 1600.00000000 mil 1.57079633 rad 1000000 5.92562114 rad 339.51308232º 377.23675814 grad 6035.78813019 mil 5.92562114 rad
J
given definitions which convert to and from the unit circle, using verbial power (^:) inverse (^: _1), and adverbs to make the sentences read better? or at least differently from other computer languages: <lang>
TAU =: 2p1 NB. tauday.com
normalize =: * * 1 | | NB. signum times the fractional part of absolute value
TurnTo=: &*
as_turn =: 1 TurnTo as_degree =: 360 TurnTo as_gradian =: 400 TurnTo as_mil =: 6400 TurnTo as_radian =: TAU TurnTo
Turn =: adverb def 'normalize as_turn inv m' Degree =: adverb def 'normalize as_degree inv m' Gradian =: adverb def 'normalize as_gradian inv m' Mil =: adverb def 'normalize as_mil inv m' Radian =: adverb def 'normalize as_radian inv m'
</lang> we can compose conversion sentences like <lang>
as_degree 100 Gradian
90 </lang> Presuming the following additional definitions: <lang>
NAMES =: > turn`degree`gradian`mil`radian ALL =: as_turn`as_degree`as_gradian`as_mil`as_radian to_all=: NAMES ; ALL`:0
VALUES =: _&".'-2 -1 0 1 2 6.2831853 16 57.2957795 359 399 6399 1000000'
to_all VALUES Turn
+-------+------------------------------------+ |turn |0 0 0 0 0 0.283185 0 0.29578 0 0 0 0| |degree |0 0 0 0 0 101.947 0 106.481 0 0 0 0| |gradian|0 0 0 0 0 113.274 0 118.312 0 0 0 0| |mil |0 0 0 0 0 1812.39 0 1892.99 0 0 0 0| |radian |0 0 0 0 0 1.77931 0 1.85844 0 0 0 0| +-------+------------------------------------+
to_all VALUES Degree
+-------+---------------------------------------------------------------------------------------------------------------+ |turn |_0.00555556 _0.00277778 0 0.00277778 0.00555556 0.0174533 0.0444444 0.159155 0.997222 0.108333 0.775 0.777778| |degree | _2 _1 0 1 2 6.28319 16 57.2958 359 39 279 280| |gradian| _2.22222 _1.11111 0 1.11111 2.22222 6.98132 17.7778 63.662 398.889 43.3333 310 311.111| |mil | _35.5556 _17.7778 0 17.7778 35.5556 111.701 284.444 1018.59 6382.22 693.333 4960 4977.78| |radian | _0.0349066 _0.0174533 0 0.0174533 0.0349066 0.109662 0.279253 1 6.26573 0.680678 4.86947 4.88692| +-------+---------------------------------------------------------------------------------------------------------------+
to_all VALUES Gradian
+-------+----------------------------------------------------------------------------------------------+ |turn | _0.005 _0.0025 0 0.0025 0.005 0.015708 0.04 0.143239 0.8975 0.9975 0.9975 0| |degree | _1.8 _0.9 0 0.9 1.8 5.65487 14.4 51.5662 323.1 359.1 359.1 0| |gradian| _2 _1 0 1 2 6.28319 16 57.2958 359 399 399 0| |mil | _32 _16 0 16 32 100.531 256 916.732 5744 6384 6384 0| |radian |_0.0314159 _0.015708 0 0.015708 0.0314159 0.098696 0.251327 0.9 5.63916 6.26748 6.26748 0| +-------+----------------------------------------------------------------------------------------------+
to_all VALUES Mil
+-------+-------------------------------------------------------------------------------------------------------------------+ |turn |_0.0003125 _0.00015625 0 0.00015625 0.0003125 0.000981748 0.0025 0.00895247 0.0560937 0.0623438 0.999844 0.25| |degree | _0.1125 _0.05625 0 0.05625 0.1125 0.353429 0.9 3.22289 20.1937 22.4438 359.944 90| |gradian| _0.125 _0.0625 0 0.0625 0.125 0.392699 1 3.58099 22.4375 24.9375 399.938 100| |mil | _2 _1 0 1 2 6.28319 16 57.2958 359 399 6399 1600| |radian |_0.0019635 _0.000981748 0 0.000981748 0.0019635 0.0061685 0.015708 0.05625 0.352447 0.391717 6.2822 1.5708| +-------+-------------------------------------------------------------------------------------------------------------------+
to_all VALUES Radian
+-------+---------------------------------------------------------------------------------------------------+ |turn |_0.31831 _0.159155 0 0.159155 0.31831 1 0.546479 0.118907 0.136625 0.502822 0.432481 0.943092| |degree |_114.592 _57.2958 0 57.2958 114.592 360 196.732 42.8063 49.1848 181.016 155.693 339.513| |gradian|_127.324 _63.662 0 63.662 127.324 400 218.592 47.5626 54.6498 201.129 172.992 377.237| |mil |_2037.18 _1018.59 0 1018.59 2037.18 6400 3497.47 761.002 874.397 3218.06 2767.88 6035.79| |radian | _2 _1 0 1 2 6.28319 3.43363 0.747112 0.858437 3.15933 2.71736 5.92562| +-------+---------------------------------------------------------------------------------------------------+ </lang>
Java
<lang java>import java.text.DecimalFormat;
// Title: Angles (geometric), normalization and conversion
public class AnglesNormalizationAndConversion {
public static void main(String[] args) { DecimalFormat formatAngle = new DecimalFormat("######0.000000"); DecimalFormat formatConv = new DecimalFormat("###0.0000"); System.out.printf(" degrees gradiens mils radians%n"); for ( double angle : new double[] {-2, -1, 0, 1, 2, 6.2831853, 16, 57.2957795, 359, 399, 6399, 1000000} ) { for ( String units : new String[] {"degrees", "gradiens", "mils", "radians"}) { double d = 0, g = 0, m = 0, r = 0; switch (units) { case "degrees": d = d2d(angle); g = d2g(d); m = d2m(d); r = d2r(d); break; case "gradiens": g = g2g(angle); d = g2d(g); m = g2m(g); r = g2r(g); break; case "mils": m = m2m(angle); d = m2d(m); g = m2g(m); r = m2r(m); break; case "radians": r = r2r(angle); d = r2d(r); g = r2g(r); m = r2m(r); break; } System.out.printf("%15s %8s = %10s %10s %10s %10s%n", formatAngle.format(angle), units, formatConv.format(d), formatConv.format(g), formatConv.format(m), formatConv.format(r)); } } }
private static final double DEGREE = 360D; private static final double GRADIAN = 400D; private static final double MIL = 6400D; private static final double RADIAN = (2 * Math.PI); private static double d2d(double a) { return a % DEGREE; } private static double d2g(double a) { return a * (GRADIAN / DEGREE); } private static double d2m(double a) { return a * (MIL / DEGREE); } private static double d2r(double a) { return a * (RADIAN / 360); }
private static double g2d(double a) { return a * (DEGREE / GRADIAN); } private static double g2g(double a) { return a % GRADIAN; } private static double g2m(double a) { return a * (MIL / GRADIAN); } private static double g2r(double a) { return a * (RADIAN / GRADIAN); } private static double m2d(double a) { return a * (DEGREE / MIL); } private static double m2g(double a) { return a * (GRADIAN / MIL); } private static double m2m(double a) { return a % MIL; } private static double m2r(double a) { return a * (RADIAN / MIL); } private static double r2d(double a) { return a * (DEGREE / RADIAN); } private static double r2g(double a) { return a * (GRADIAN / RADIAN); } private static double r2m(double a) { return a * (MIL / RADIAN); } private static double r2r(double a) { return a % RADIAN; }
}</lang>
- Output:
degrees gradiens mils radians -2.000000 degrees = -2.0000 -2.2222 -35.5556 -0.0349 -2.000000 gradiens = -1.8000 -2.0000 -32.0000 -0.0314 -2.000000 mils = -0.1125 -0.1250 -2.0000 -0.0020 -2.000000 radians = -114.5916 -127.3240 -2037.1833 -2.0000 -1.000000 degrees = -1.0000 -1.1111 -17.7778 -0.0175 -1.000000 gradiens = -0.9000 -1.0000 -16.0000 -0.0157 -1.000000 mils = -0.0563 -0.0625 -1.0000 -0.0010 -1.000000 radians = -57.2958 -63.6620 -1018.5916 -1.0000 0.000000 degrees = 0.0000 0.0000 0.0000 0.0000 0.000000 gradiens = 0.0000 0.0000 0.0000 0.0000 0.000000 mils = 0.0000 0.0000 0.0000 0.0000 0.000000 radians = 0.0000 0.0000 0.0000 0.0000 1.000000 degrees = 1.0000 1.1111 17.7778 0.0175 1.000000 gradiens = 0.9000 1.0000 16.0000 0.0157 1.000000 mils = 0.0563 0.0625 1.0000 0.0010 1.000000 radians = 57.2958 63.6620 1018.5916 1.0000 2.000000 degrees = 2.0000 2.2222 35.5556 0.0349 2.000000 gradiens = 1.8000 2.0000 32.0000 0.0314 2.000000 mils = 0.1125 0.1250 2.0000 0.0020 2.000000 radians = 114.5916 127.3240 2037.1833 2.0000 6.283185 degrees = 6.2832 6.9813 111.7011 0.1097 6.283185 gradiens = 5.6549 6.2832 100.5310 0.0987 6.283185 mils = 0.3534 0.3927 6.2832 0.0062 6.283185 radians = 360.0000 400.0000 6400.0000 6.2832 16.000000 degrees = 16.0000 17.7778 284.4444 0.2793 16.000000 gradiens = 14.4000 16.0000 256.0000 0.2513 16.000000 mils = 0.9000 1.0000 16.0000 0.0157 16.000000 radians = 196.7325 218.5916 3497.4662 3.4336 57.295780 degrees = 57.2958 63.6620 1018.5916 1.0000 57.295780 gradiens = 51.5662 57.2958 916.7325 0.9000 57.295780 mils = 3.2229 3.5810 57.2958 0.0562 57.295780 radians = 42.8063 47.5626 761.0018 0.7471 359.000000 degrees = 359.0000 398.8889 6382.2222 6.2657 359.000000 gradiens = 323.1000 359.0000 5744.0000 5.6392 359.000000 mils = 20.1938 22.4375 359.0000 0.3524 359.000000 radians = 49.1848 54.6498 874.3972 0.8584 399.000000 degrees = 39.0000 43.3333 693.3333 0.6807 399.000000 gradiens = 359.1000 399.0000 6384.0000 6.2675 399.000000 mils = 22.4438 24.9375 399.0000 0.3917 399.000000 radians = 181.0160 201.1289 3218.0627 3.1593 6399.000000 degrees = 279.0000 310.0000 4960.0000 4.8695 6399.000000 gradiens = 359.1000 399.0000 6384.0000 6.2675 6399.000000 mils = 359.9438 399.9375 6399.0000 6.2822 6399.000000 radians = 155.6931 172.9923 2767.8774 2.7174 1000000.000000 degrees = 280.0000 311.1111 4977.7778 4.8869 1000000.000000 gradiens = 0.0000 0.0000 0.0000 0.0000 1000000.000000 mils = 90.0000 100.0000 1600.0000 1.5708 1000000.000000 radians = 339.5131 377.2368 6035.7881 5.9256
Julia
<lang julia>using Formatting
d2d(d) = d % 360 g2g(g) = g % 400 m2m(m) = m % 6400 r2r(r) = r % 2π d2g(d) = d2d(d) * 10 / 9 d2m(d) = d2d(d) * 160 / 9 d2r(d) = d2d(d) * π / 180 g2d(g) = g2g(g) * 9 / 10 g2m(g) = g2g(g) * 16 g2r(g) = g2g(g) * π / 200 m2d(m) = m2m(m) * 9 / 160 m2g(m) = m2m(m) / 16 m2r(m) = m2m(m) * π / 3200 r2d(r) = r2r(r) * 180 / π r2g(r) = r2r(r) * 200 / π r2m(r) = r2r(r) * 3200 / π
fmt(x::Real, width=16) = Int(round(x)) == x ? rpad(Int(x), width) :
rpad(format(x, precision=7), width)
fmt(x::String, width=16) = rpad(x, width)
const t2u = Dict("degrees" => [d2d, d2g, d2m, d2r],
"gradians" => [g2d, g2g, g2m, g2r], "mils" => [m2d, m2g, m2m, m2r], "radians" => [r2d, r2g, r2m, r2r])
function testconversions(arr)
println("Number Units Degrees Gradians Mils Radians") for num in arr, units in ["degrees", "gradians", "mils", "radians"] print(fmt(num), fmt(units)) for f in t2u[units] print(fmt(f(num))) end println() end
end
testconversions([-2, -1, 0, 1, 2, 6.2831853, 16, 57.2957795, 359, 399, 6399, 1000000])
</lang>
- Output:
Number Units Degrees Gradians Mils Radians -2 degrees -2 -2.2222222 -35.5555556 -0.0349066 -2 gradians -1.8000000 -2 -32 -0.0314159 -2 mils -0.1125000 -0.1250000 -2 -0.0019635 -2 radians -114.5915590 -127.3239545 -2037.1832716 -2 -1 degrees -1 -1.1111111 -17.7777778 -0.0174533 -1 gradians -0.9000000 -1 -16 -0.0157080 -1 mils -0.0562500 -0.0625000 -1 -0.0009817 -1 radians -57.2957795 -63.6619772 -1018.5916358 -1 0 degrees 0 0 0 0 0 gradians 0 0 0 0 0 mils 0 0 0 0 0 radians 0 0 0 0 1 degrees 1 1.1111111 17.7777778 0.0174533 1 gradians 0.9000000 1 16 0.0157080 1 mils 0.0562500 0.0625000 1 0.0009817 1 radians 57.2957795 63.6619772 1018.5916358 1 2 degrees 2 2.2222222 35.5555556 0.0349066 2 gradians 1.8000000 2 32 0.0314159 2 mils 0.1125000 0.1250000 2 0.0019635 2 radians 114.5915590 127.3239545 2037.1832716 2 6.2831853 degrees 6.2831853 6.9813170 111.7010720 0.1096623 6.2831853 gradians 5.6548668 6.2831853 100.5309648 0.0986960 6.2831853 mils 0.3534292 0.3926991 6.2831853 0.0061685 6.2831853 radians 359.9999996 399.9999995 6399.9999927 6.2831853 16 degrees 16 17.7777778 284.4444444 0.2792527 16 gradians 14.4000000 16 256 0.2513274 16 mils 0.9000000 1 16 0.0157080 16 radians 196.7324722 218.5916358 3497.4661726 3.4336294 57.2957795 degrees 57.2957795 63.6619772 1018.5916356 1.0000000 57.2957795 gradians 51.5662016 57.2957795 916.7324720 0.9000000 57.2957795 mils 3.2228876 3.5809862 57.2957795 0.0562500 57.2957795 radians 42.8063493 47.5626103 761.0017647 0.7471117 359 degrees 359 398.8888889 6382.2222222 6.2657320 359 gradians 323.1000000 359 5744 5.6391588 359 mils 20.1937500 22.4375000 359 0.3524474 359 radians 49.1848452 54.6498280 874.3972479 0.8584375 399 degrees 39 43.3333333 693.3333333 0.6806784 399 gradians 359.1000000 399 6384 6.2674773 399 mils 22.4437500 24.9375000 399 0.3917173 399 radians 181.0160257 201.1289175 3218.0626795 3.1593256 6399 degrees 279 310 4960 4.8694686 6399 gradians 359.1000000 399 6384 6.2674773 6399 mils 359.9437500 399.9375000 6399 6.2822036 6399 radians 155.6931042 172.9923380 2767.8774082 2.7173573 1000000 degrees 280 311.1111111 4977.7777778 4.8869219 1000000 gradians 0 0 0 0 1000000 mils 90 100 1600 1.5707963 1000000 radians 339.5130823 377.2367581 6035.7881302 5.9256211
Kotlin
<lang scala>import java.text.DecimalFormat as DF
const val DEGREE = 360.0 const val GRADIAN = 400.0 const val MIL = 6400.0 const val RADIAN = 2 * Math.PI
fun d2d(a: Double) = a % DEGREE fun d2g(a: Double) = a * (GRADIAN / DEGREE) fun d2m(a: Double) = a * (MIL / DEGREE) fun d2r(a: Double) = a * (RADIAN / 360) fun g2d(a: Double) = a * (DEGREE / GRADIAN) fun g2g(a: Double) = a % GRADIAN fun g2m(a: Double) = a * (MIL / GRADIAN) fun g2r(a: Double) = a * (RADIAN / GRADIAN) fun m2d(a: Double) = a * (DEGREE / MIL) fun m2g(a: Double) = a * (GRADIAN / MIL) fun m2m(a: Double) = a % MIL fun m2r(a: Double) = a * (RADIAN / MIL) fun r2d(a: Double) = a * (DEGREE / RADIAN) fun r2g(a: Double) = a * (GRADIAN / RADIAN) fun r2m(a: Double) = a * (MIL / RADIAN) fun r2r(a: Double) = a % RADIAN
fun main() {
val fa = DF("######0.000000") val fc = DF("###0.0000") println(" degrees gradiens mils radians") for (a in listOf(-2.0, -1.0, 0.0, 1.0, 2.0, 6.2831853, 16.0, 57.2957795, 359.0, 399.0, 6399.0, 1000000.0)) for (units in listOf("degrees", "gradiens", "mils", "radians")) { val (d,g,m,r) = when (units) { "degrees" -> { val d = d2d(a) listOf(d, d2g(d), d2m(d), d2r(d)) } "gradiens" -> { val g = g2g(a) listOf(g2d(g), g, g2m(g), g2r(g)) } "mils" -> { val m = m2m(a) listOf(m2d(m), m2g(m), m, m2r(m)) } "radians" -> { val r = r2r(a) listOf(r2d(r), r2g(r), r2m(r), r) } else -> emptyList() }
println("%15s %8s = %10s %10s %10s %10s".format(fa.format(a), units, fc.format(d), fc.format(g), fc.format(m), fc.format(r))) }
}</lang>
- Output:
See Java output
Lua
<lang lua>range = { degrees=360, gradians=400, mils=6400, radians=2.0*math.pi } function convert(value, fromunit, tounit)
return math.fmod(value * range[tounit] / range[fromunit], range[tounit])
end
testvalues = { -2, -1, 0, 1, 2, 6.2831853, 16, 57.2957795, 359, 399, 6399, 1000000 } testunits = { "degrees", "gradians", "mils", "radians" } print(string.format("%15s %8s = %15s %15s %15s %15s", "VALUE", "UNIT", "DEGREES", "GRADIANS", "MILS", "RADIANS")) for _, value in ipairs(testvalues) do
for _, fromunit in ipairs(testunits) do local d = convert(value, fromunit, "degrees") local g = convert(value, fromunit, "gradians") local m = convert(value, fromunit, "mils") local r = convert(value, fromunit, "radians") print(string.format("%15.7f %8s = %15.7f %15.7f %15.7f %15.7f", value, fromunit, d, g, m, r)) end
end</lang> Optionally: <lang lua>-- if you care.. assert(convert(-360,"degrees","degrees") == 0.0) assert(convert(360,"degrees","degrees") == 0.0) assert(convert(-400,"gradians","gradians") == 0.0) assert(convert(400,"gradians","gradians") == 0.0) assert(convert(-6400,"mils","mils") == 0.0) assert(convert(6400,"mils","mils") == 0.0) assert(convert(-2.0*math.pi,"radians","radians") == 0.0) assert(convert(2.0*math.pi,"radians","radians") == 0.0)
-- if you must.. function d2d(n) return convert(n,"degrees","degrees") end function d2g(n) return convert(n,"degrees","gradians") end function d2m(n) return convert(n,"degrees","mils") end function d2r(n) return convert(n,"degrees","radians") end function g2d(n) return convert(n,"gradians","degrees") end function g2g(n) return convert(n,"gradians","gradians") end function g2m(n) return convert(n,"gradians","mils") end function g2r(n) return convert(n,"gradians","radians") end function m2d(n) return convert(n,"mils","degrees") end function m2g(n) return convert(n,"mils","gradians") end function m2m(n) return convert(n,"mils","mils") end function m2r(n) return convert(n,"mils","radians") end function r2d(n) return convert(n,"radians","degrees") end function r2g(n) return convert(n,"radians","gradians") end function r2m(n) return convert(n,"radians","mils") end function r2r(n) return convert(n,"radians","radians") end</lang>
- Output:
VALUE UNIT = DEGREES GRADIANS MILS RADIANS -2.0000000 degrees = -2.0000000 -2.2222222 -35.5555556 -0.0349066 -2.0000000 gradians = -1.8000000 -2.0000000 -32.0000000 -0.0314159 -2.0000000 mils = -0.1125000 -0.1250000 -2.0000000 -0.0019635 -2.0000000 radians = -114.5915590 -127.3239545 -2037.1832716 -2.0000000 -1.0000000 degrees = -1.0000000 -1.1111111 -17.7777778 -0.0174533 -1.0000000 gradians = -0.9000000 -1.0000000 -16.0000000 -0.0157080 -1.0000000 mils = -0.0562500 -0.0625000 -1.0000000 -0.0009817 -1.0000000 radians = -57.2957795 -63.6619772 -1018.5916358 -1.0000000 0.0000000 degrees = 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 gradians = 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 mils = 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 radians = 0.0000000 0.0000000 0.0000000 0.0000000 1.0000000 degrees = 1.0000000 1.1111111 17.7777778 0.0174533 1.0000000 gradians = 0.9000000 1.0000000 16.0000000 0.0157080 1.0000000 mils = 0.0562500 0.0625000 1.0000000 0.0009817 1.0000000 radians = 57.2957795 63.6619772 1018.5916358 1.0000000 2.0000000 degrees = 2.0000000 2.2222222 35.5555556 0.0349066 2.0000000 gradians = 1.8000000 2.0000000 32.0000000 0.0314159 2.0000000 mils = 0.1125000 0.1250000 2.0000000 0.0019635 2.0000000 radians = 114.5915590 127.3239545 2037.1832716 2.0000000 6.2831853 degrees = 6.2831853 6.9813170 111.7010720 0.1096623 6.2831853 gradians = 5.6548668 6.2831853 100.5309648 0.0986960 6.2831853 mils = 0.3534292 0.3926991 6.2831853 0.0061685 6.2831853 radians = 359.9999996 399.9999995 6399.9999927 6.2831853 16.0000000 degrees = 16.0000000 17.7777778 284.4444444 0.2792527 16.0000000 gradians = 14.4000000 16.0000000 256.0000000 0.2513274 16.0000000 mils = 0.9000000 1.0000000 16.0000000 0.0157080 16.0000000 radians = 196.7324722 218.5916358 3497.4661726 3.4336294 57.2957795 degrees = 57.2957795 63.6619772 1018.5916356 1.0000000 57.2957795 gradians = 51.5662016 57.2957795 916.7324720 0.9000000 57.2957795 mils = 3.2228876 3.5809862 57.2957795 0.0562500 57.2957795 radians = 42.8063493 47.5626103 761.0017647 0.7471117 359.0000000 degrees = 359.0000000 398.8888889 6382.2222222 6.2657320 359.0000000 gradians = 323.1000000 359.0000000 5744.0000000 5.6391588 359.0000000 mils = 20.1937500 22.4375000 359.0000000 0.3524474 359.0000000 radians = 49.1848452 54.6498280 874.3972479 0.8584375 399.0000000 degrees = 39.0000000 43.3333333 693.3333333 0.6806784 399.0000000 gradians = 359.1000000 399.0000000 6384.0000000 6.2674773 399.0000000 mils = 22.4437500 24.9375000 399.0000000 0.3917173 399.0000000 radians = 181.0160257 201.1289175 3218.0626795 3.1593256 6399.0000000 degrees = 279.0000000 310.0000000 4960.0000000 4.8694686 6399.0000000 gradians = 359.1000000 399.0000000 6384.0000000 6.2674773 6399.0000000 mils = 359.9437500 399.9375000 6399.0000000 6.2822036 6399.0000000 radians = 155.6931042 172.9923380 2767.8774082 2.7173573 1000000.0000000 degrees = 280.0000000 311.1111111 4977.7777778 4.8869219 1000000.0000000 gradians = 0.0000000 0.0000000 0.0000000 0.0000000 1000000.0000000 mils = 90.0000000 100.0000000 1600.0000000 1.5707963 1000000.0000000 radians = 339.5130823 377.2367581 6035.7881302 5.9256211
Mathematica/Wolfram Language
<lang Mathematica>ClearAll[NormalizeAngle, NormalizeDegree, NormalizeGradian, NormalizeMil, NormalizeRadian] NormalizeAngle[d_, full_] := Module[{a = d},
If[Abs[a/full] > 4, a = a - Sign[a] full (Quotient[Abs[a], full] - 4) ]; While[a < -full, a += full]; While[a > full, a -= full]; a ]
ClearAll[Degree2Gradian, Degree2Mil, Degree2Radian, Gradian2Degree, Gradian2Mil, Gradian2Radian, Mil2Degree, Mil2Gradian, Mil2Radian, Radian2Degree, Radian2Gradian, Radian2Mil] NormalizeDegree[d_] := NormalizeAngle[d, 360] NormalizeGradian[d_] := NormalizeAngle[d, 400] NormalizeMil[d_] := NormalizeAngle[d, 6400] NormalizeRadian[d_] := NormalizeAngle[d, 2 Pi] Degree2Gradian[d_] := d 400/360 Degree2Mil[d_] := d 6400/360 Degree2Radian[d_] := d Pi/180 Gradian2Degree[d_] := d 360/400 Gradian2Mil[d_] := d 6400/400 Gradian2Radian[d_] := d 2 Pi/400 Mil2Degree[d_] := d 360/6400 Mil2Gradian[d_] := d 400/6400 Mil2Radian[d_] := d 2 Pi/6400 Radian2Degree[d_] := d 180/Pi Radian2Gradian[d_] := d 400/(2 Pi) Radian2Mil[d_] := d 6400/(2 Pi) MapThread[Construct, {{Degree2Gradian, Degree2Mil, Degree2Radian,
Gradian2Degree, Gradian2Mil, Gradian2Radian, Mil2Degree, Mil2Gradian, Mil2Radian, Radian2Degree, Radian2Gradian, Radian2Mil}, {-2, -1, 0, 1, 2, 6.2831853, 16, 57.2957795, 359, 399, 6399, 1000000}}]</lang>
- Output:
{-(20/9),-(160/9),0,9/10,32,0.098696,9/10,3.58099,(359 \[Pi])/3200,71820/\[Pi],1279800/\[Pi],3200000000/\[Pi]}
Nim
<lang Nim>import math import strformat
const Values = [float -2, -1, 0, 1, 2, 6.2831853, 16, 57.2957795, 359, 399, 6399, 1000000]
func d2d(x: float): float {.inline.} = x mod 360 func g2g(x: float): float {.inline.} = x mod 400 func m2m(x: float): float {.inline.} = x mod 6400 func r2r(x: float): float {.inline.} = x mod (2 * Pi)
func d2g(x: float): float {.inline.} = d2d(x) * 10 / 9 func d2m(x: float): float {.inline.} = d2d(x) * 160 / 9 func d2r(x: float): float {.inline.} = d2d(x) * Pi / 180
func g2d(x: float): float {.inline.} = g2g(x) * 9 / 10 func g2m(x: float): float {.inline.} = g2g(x) * 16 func g2r(x: float): float {.inline.} = g2g(x) * Pi / 200
func m2d(x: float): float {.inline.} = m2m(x) * 9 / 160 func m2g(x: float): float {.inline.} = m2m(x) / 16 func m2r(x: float): float {.inline.} = m2m(x) * Pi / 3200
func r2d(x: float): float {.inline.} = r2r(x) * 180 / Pi func r2g(x: float): float {.inline.} = r2r(x) * 200 / Pi func r2m(x: float): float {.inline.} = r2r(x) * 3200 / Pi
- Normalizing and converting degrees.
echo " Degrees Normalized Gradians Mils Radians" echo "———————————————————————————————————————————————————————————————————————————————————" for val in Values:
echo fmt"{val:15.7f} {d2d(val):15.7f} {d2g(val):15.7f} {d2m(val):15.7f} {d2r(val):15.7f}"
- Normalizing and converting gradians.
echo "" echo " Gradians Normalized Degrees Mils Radians" echo "———————————————————————————————————————————————————————————————————————————————————" for val in Values:
echo fmt"{val:15.7f} {g2g(val):15.7f} {g2d(val):15.7f} {g2m(val):15.7f} {g2r(val):15.7f}"
- Normalizing and converting mils.
echo "" echo " Mils Normalized Degrees Gradians Radians" echo "———————————————————————————————————————————————————————————————————————————————————" for val in Values:
echo fmt"{val:15.7f} {m2m(val):15.7f} {m2d(val):15.7f} {m2g(val):15.7f} {m2r(val):15.7f}"
- Normalizing and converting radians.
echo "" echo " Radians Normalized Degrees Gradians Mils" echo "———————————————————————————————————————————————————————————————————————————————————" for val in Values:
echo fmt"{val:15.7f} {r2r(val):15.7f} {r2d(val):15.7f} {r2g(val):15.7f} {r2m(val):15.7f}"</lang>
- Output:
Degrees Normalized Gradians Mils Radians ——————————————————————————————————————————————————————————————————————————————————— -2.0000000 -2.0000000 -2.2222222 -35.5555556 -0.0349066 -1.0000000 -1.0000000 -1.1111111 -17.7777778 -0.0174533 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 1.0000000 1.0000000 1.1111111 17.7777778 0.0174533 2.0000000 2.0000000 2.2222222 35.5555556 0.0349066 6.2831853 6.2831853 6.9813170 111.7010720 0.1096623 16.0000000 16.0000000 17.7777778 284.4444444 0.2792527 57.2957795 57.2957795 63.6619772 1018.5916356 1.0000000 359.0000000 359.0000000 398.8888889 6382.2222222 6.2657320 399.0000000 39.0000000 43.3333333 693.3333333 0.6806784 6399.0000000 279.0000000 310.0000000 4960.0000000 4.8694686 1000000.0000000 280.0000000 311.1111111 4977.7777778 4.8869219 Gradians Normalized Degrees Mils Radians ——————————————————————————————————————————————————————————————————————————————————— -2.0000000 -2.0000000 -1.8000000 -32.0000000 -0.0314159 -1.0000000 -1.0000000 -0.9000000 -16.0000000 -0.0157080 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 1.0000000 1.0000000 0.9000000 16.0000000 0.0157080 2.0000000 2.0000000 1.8000000 32.0000000 0.0314159 6.2831853 6.2831853 5.6548668 100.5309648 0.0986960 16.0000000 16.0000000 14.4000000 256.0000000 0.2513274 57.2957795 57.2957795 51.5662016 916.7324720 0.9000000 359.0000000 359.0000000 323.1000000 5744.0000000 5.6391588 399.0000000 399.0000000 359.1000000 6384.0000000 6.2674773 6399.0000000 399.0000000 359.1000000 6384.0000000 6.2674773 1000000.0000000 0.0000000 0.0000000 0.0000000 0.0000000 Mils Normalized Degrees Gradians Radians ——————————————————————————————————————————————————————————————————————————————————— -2.0000000 -2.0000000 -0.1125000 -0.1250000 -0.0019635 -1.0000000 -1.0000000 -0.0562500 -0.0625000 -0.0009817 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 1.0000000 1.0000000 0.0562500 0.0625000 0.0009817 2.0000000 2.0000000 0.1125000 0.1250000 0.0019635 6.2831853 6.2831853 0.3534292 0.3926991 0.0061685 16.0000000 16.0000000 0.9000000 1.0000000 0.0157080 57.2957795 57.2957795 3.2228876 3.5809862 0.0562500 359.0000000 359.0000000 20.1937500 22.4375000 0.3524474 399.0000000 399.0000000 22.4437500 24.9375000 0.3917173 6399.0000000 6399.0000000 359.9437500 399.9375000 6.2822036 1000000.0000000 1600.0000000 90.0000000 100.0000000 1.5707963 Radians Normalized Degrees Gradians Mils ——————————————————————————————————————————————————————————————————————————————————— -2.0000000 -2.0000000 -114.5915590 -127.3239545 -2037.1832716 -1.0000000 -1.0000000 -57.2957795 -63.6619772 -1018.5916358 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000 1.0000000 1.0000000 57.2957795 63.6619772 1018.5916358 2.0000000 2.0000000 114.5915590 127.3239545 2037.1832716 6.2831853 6.2831853 359.9999996 399.9999995 6399.9999927 16.0000000 3.4336294 196.7324722 218.5916358 3497.4661726 57.2957795 0.7471117 42.8063493 47.5626103 761.0017647 359.0000000 0.8584375 49.1848452 54.6498280 874.3972479 399.0000000 3.1593256 181.0160257 201.1289175 3218.0626795 6399.0000000 2.7173573 155.6931042 172.9923380 2767.8774082 1000000.0000000 5.9256211 339.5130823 377.2367581 6035.7881302
Perl
<lang perl>use strict; use warnings; use feature 'say'; use POSIX 'fmod';
my $tau = 2 * 4*atan2(1, 1); my @units = (
{ code => 'd', name => 'degrees' , number => 360 }, { code => 'g', name => 'gradians', number => 400 }, { code => 'm', name => 'mills' , number => 6400 }, { code => 'r', name => 'radians' , number => $tau },
);
my %cvt; for my $a (@units) {
for my $b (@units) { $cvt{ "${$a}{code}2${$b}{code}" } = sub { my($angle) = shift; my $norm = fmod($angle,${$a}{number}); # built-in '%' returns only integers $norm -= ${$a}{number} if $angle < 0; $norm * ${$b}{number} / ${$a}{number} } }
}
printf '%s'. '%12s'x4 . "\n", ' Angle Unit ', <Degrees Gradians Mills Radians>; for my $angle (-2, -1, 0, 1, 2, $tau, 16, 360/$tau, 360-1, 400-1, 6400-1, 1_000_000) {
print "\n"; for my $from (@units) { my @sub_keys = map { "${$from}{code}2${$_}{code}" } @units; my @results = map { &{$cvt{$_}}($angle) } @sub_keys; printf '%10g %-8s' . '%12g'x4 . "\n", $angle, ${$from}{name}, @results; }
}</lang>
- Output:
Angle Unit Degrees Gradians Mills Radians -2 degrees -362 -402.222 -6435.56 -6.31809 -2 gradians -361.8 -402 -6432 -6.3146 -2 mills -360.113 -400.125 -6402 -6.28515 -2 radians -474.592 -527.324 -8437.18 -8.28319 -1 degrees -361 -401.111 -6417.78 -6.30064 -1 gradians -360.9 -401 -6416 -6.29889 -1 mills -360.056 -400.062 -6401 -6.28417 -1 radians -417.296 -463.662 -7418.59 -7.28319 0 degrees 0 0 0 0 0 gradians 0 0 0 0 0 mills 0 0 0 0 0 radians 0 0 0 0 1 degrees 1 1.11111 17.7778 0.0174533 1 gradians 0.9 1 16 0.015708 1 mills 0.05625 0.0625 1 0.000981748 1 radians 57.2958 63.662 1018.59 1 2 degrees 2 2.22222 35.5556 0.0349066 2 gradians 1.8 2 32 0.0314159 2 mills 0.1125 0.125 2 0.0019635 2 radians 114.592 127.324 2037.18 2 6.28319 degrees 6.28319 6.98132 111.701 0.109662 6.28319 gradians 5.65487 6.28319 100.531 0.098696 6.28319 mills 0.353429 0.392699 6.28319 0.0061685 6.28319 radians 0 0 0 0 16 degrees 16 17.7778 284.444 0.279253 16 gradians 14.4 16 256 0.251327 16 mills 0.9 1 16 0.015708 16 radians 196.732 218.592 3497.47 3.43363 57.2958 degrees 57.2958 63.662 1018.59 1 57.2958 gradians 51.5662 57.2958 916.732 0.9 57.2958 mills 3.22289 3.58099 57.2958 0.05625 57.2958 radians 42.8064 47.5626 761.002 0.747112 359 degrees 359 398.889 6382.22 6.26573 359 gradians 323.1 359 5744 5.63916 359 mills 20.1938 22.4375 359 0.352447 359 radians 49.1848 54.6498 874.397 0.858437 399 degrees 39 43.3333 693.333 0.680678 399 gradians 359.1 399 6384 6.26748 399 mills 22.4438 24.9375 399 0.391717 399 radians 181.016 201.129 3218.06 3.15933 6399 degrees 279 310 4960 4.86947 6399 gradians 359.1 399 6384 6.26748 6399 mills 359.944 399.938 6399 6.2822 6399 radians 155.693 172.992 2767.88 2.71736 1e+06 degrees 280 311.111 4977.78 4.88692 1e+06 gradians 0 0 0 0 1e+06 mills 90 100 1600 1.5708 1e+06 radians 339.513 377.237 6035.79 5.92562
Phix
Obviously if preferred you could define a long list of routines such as function d2g(atom a) return remainder(a/360,1)*400 end function
constant units = {"degrees","gradians","mils","radians"}, turns = {1/360,1/400,1/6400,0.5/PI} function convert(atom a, integer fdx, tdx) return remainder(a*turns[fdx],1)/turns[tdx] end function constant tests = {-2,-1,0,1,2,2*PI,16,57.2957795,359,399,6399,1000000} printf(1," angle unit %9s %9s %9s %9s\n",units) for i=1 to length(tests) do for fdx=1 to length(units) do printf(1,"%9g %-8s",{tests[i],units[fdx]}) for tdx=1 to length(units) do printf(1," %9g",convert(tests[i],fdx,tdx)) end for puts(1,"\n") end for puts(1,"\n") end for
- Output:
angle unit degrees gradians mils radians -2 degrees -2 -2.22222 -35.5556 -0.034907 -2 gradians -1.8 -2 -32 -0.031416 -2 mils -0.1125 -0.125 -2 -0.001963 -2 radians -114.592 -127.324 -2037.18 -2 -1 degrees -1 -1.11111 -17.7778 -0.017453 -1 gradians -0.9 -1 -16 -0.015708 -1 mils -0.05625 -0.0625 -1 -0.000982 -1 radians -57.2958 -63.662 -1018.59 -1 0 degrees 0 0 0 0 0 gradians 0 0 0 0 0 mils 0 0 0 0 0 radians 0 0 0 0 1 degrees 1 1.11111 17.7778 0.017453 1 gradians 0.9 1 16 0.015708 1 mils 0.05625 0.0625 1 0.000982 1 radians 57.2958 63.662 1018.59 1 2 degrees 2 2.22222 35.5556 0.034907 2 gradians 1.8 2 32 0.031416 2 mils 0.1125 0.125 2 0.001963 2 radians 114.592 127.324 2037.18 2 6.28319 degrees 6.28319 6.98132 111.701 0.109662 6.28319 gradians 5.65487 6.28319 100.531 0.098696 6.28319 mils 0.353429 0.392699 6.28319 0.006169 6.28319 radians 0 0 0 0 16 degrees 16 17.7778 284.444 0.279253 16 gradians 14.4 16 256 0.251327 16 mils 0.9 1 16 0.015708 16 radians 196.732 218.592 3497.47 3.43363 57.2958 degrees 57.2958 63.662 1018.59 1 57.2958 gradians 51.5662 57.2958 916.732 0.9 57.2958 mils 3.22289 3.58099 57.2958 0.05625 57.2958 radians 42.8063 47.5626 761.002 0.747112 359 degrees 359 398.889 6382.22 6.26573 359 gradians 323.1 359 5744 5.63916 359 mils 20.1937 22.4375 359 0.352447 359 radians 49.1848 54.6498 874.397 0.858437 399 degrees 39 43.3333 693.333 0.680678 399 gradians 359.1 399 6384 6.26748 399 mils 22.4438 24.9375 399 0.391717 399 radians 181.016 201.129 3218.06 3.15933 6399 degrees 279 310 4960 4.86947 6399 gradians 359.1 399 6384 6.26748 6399 mils 359.944 399.938 6399 6.2822 6399 radians 155.693 172.992 2767.88 2.71736 1e+6 degrees 280 311.111 4977.78 4.88692 1e+6 gradians 0 0 0 0 1e+6 mils 90 100 1600 1.5708 1e+6 radians 339.513 377.237 6035.79 5.92562
Python
Python: Original
<lang python>PI = 3.141592653589793 TWO_PI = 6.283185307179586
def normalize2deg(a):
while a < 0: a += 360 while a >= 360: a -= 360 return a
def normalize2grad(a):
while a < 0: a += 400 while a >= 400: a -= 400 return a
def normalize2mil(a):
while a < 0: a += 6400 while a >= 6400: a -= 6400 return a
def normalize2rad(a):
while a < 0: a += TWO_PI while a >= TWO_PI: a -= TWO_PI return a
def deg2grad(a): return a * 10.0 / 9.0 def deg2mil(a): return a * 160.0 / 9.0 def deg2rad(a): return a * PI / 180.0
def grad2deg(a): return a * 9.0 / 10.0 def grad2mil(a): return a * 16.0 def grad2rad(a): return a * PI / 200.0
def mil2deg(a): return a * 9.0 / 160.0 def mil2grad(a): return a / 16.0 def mil2rad(a): return a * PI / 3200.0
def rad2deg(a): return a * 180.0 / PI def rad2grad(a): return a * 200.0 / PI def rad2mil(a): return a * 3200.0 / PI</lang>
Python: using tkinter
<lang python> Python 3.6.5 code using Tkinter graphical user interface.
Angles (geometric), normalization and conversion challenge. User enteres value for angle and selects a unit, then presses 'Convert' button. Values for that angle are shown in degrees, grads, mils and radians.
from tkinter import * from tkinter import messagebox import math
class Angle:
def __init__(self, gw): self.window = gw self.unit = StringVar() self.unit.set(' ') a1 = "(Enter 'Angle' & select 'Unit'," a2 = "then click 'Convert')" self.msga = a1 + '\n' + a2
# dictionary of functions to execute depending # on which radio button was selected: self.d_to_deg = {'d':self.d2d, 'g':self.g2d, 'm':self.m2d, 'r':self.r2d}
# top frame: self.top_fr = Frame(gw, width=600, height=100, bg='dodger blue') self.top_fr.pack(fill=X)
self.hdg = Label(self.top_fr, text=' Angle Conversion ', font='arial 22 bold', fg='navy', bg='lemon chiffon') self.hdg.place(relx=0.5, rely=0.5, anchor=CENTER)
self.close_btn = Button(self.top_fr, text='Quit', bd=5, bg='navy', fg='lemon chiffon', font='arial 12 bold', command=self.close_window) self.close_btn.place(relx=0.07, rely=0.5, anchor=W)
self.clear_btn = Button(self.top_fr, text='Clear', bd=5, bg='navy', fg='lemon chiffon', font='arial 12 bold', command=self.clear_screen) self.clear_btn.place(relx=0.92, rely=0.5, anchor=E)
# bottom frame: self.btm_fr = Frame(gw, width=600, height=500, bg='lemon chiffon') self.btm_fr.pack(fill=X) self.msg = Label(self.btm_fr, text=self.msga, font='arial 16 bold', fg='navy', bg='lemon chiffon') self.msg.place(relx=0.5, rely=0.1, anchor=CENTER) self.nbr_fr = LabelFrame(self.btm_fr, text=' Angle ', bg='dodger blue', fg='navy', bd=4, relief=RIDGE, font='arial 12 bold') self.nbr_fr.place(relx=0.17, rely=0.27, anchor=CENTER)
self.nbr_ent = Entry(self.nbr_fr, justify='center', font='arial 12 bold', fg='navy', bg='lemon chiffon', bd=4, width=10) self.nbr_ent.grid(row=0, column=0, padx=(8,8), pady=(8,8))
self.su_fr = LabelFrame(self.btm_fr, text=' Select Unit ', bg='dodger blue', fg='navy', bd=8, relief=RIDGE, font='arial 12 bold') self.su_fr.place(relx=0.48, rely=0.35, anchor=CENTER)
self.radiod = Radiobutton(self.su_fr, text='degree', font='arial 12 bold', fg='navy', bg='dodger blue', variable=self.unit, value='d') self.radiod.pack(side='top', anchor='w')
self.radiog = Radiobutton(self.su_fr, text='gradian', font='arial 12 bold', fg='navy', bg='dodger blue', variable=self.unit, value='g') self.radiog.pack(side='top', anchor='w')
self.radiom = Radiobutton(self.su_fr, text='mil', font='arial 12 bold', fg='navy', bg='dodger blue', variable=self.unit, value='m') self.radiom.pack(side='top', anchor='w')
self.radior = Radiobutton(self.su_fr, text='radian', font='arial 12 bold', fg='navy', bg='dodger blue', variable=self.unit, value='r') self.radior.pack(side='top', anchor='w')
self.convert_btn = Button(self.btm_fr, text='Convert', width=14, bd=5, bg='dodger blue', fg='navy', font='arial 12 bold', command=self.convert) self.convert_btn.place(relx=0.93, rely=.25, anchor=E)
self.res_fr = LabelFrame(self.btm_fr, text=' Results ', bg='dodger blue', fg='navy', bd=8, width=230, height=130, relief=RIDGE, font='arial 12 bold') self.res_fr.place(relx=0.48, rely=0.74, anchor=CENTER)
objh = 20 # widget height lblw = 80 # label width valw = 100 # value width lblx = 15 # x-position of label in frame valx = 100 # x-position of value in frame objy = 5 # y-position of widget in frame
self.deg_lbl = Label(self.res_fr, text=' degrees: ', anchor=E, font='"Noto Mono" 12 bold', fg='navy', bg='lemon chiffon') self.deg_lbl.place(x=lblx, y=objy, height=objh, width=lblw)
self.deg_val = Label(self.res_fr, text=' ', anchor=E, padx = 3, font='"Noto Mono" 12 bold', fg='navy', bg='lemon chiffon') self.deg_val.place(x=valx, y=objy, height=objh, width=valw)
objy = objy + objh # next row self.grd_lbl = Label(self.res_fr, text=' grads: ', anchor=E, font='"Noto Mono" 12 bold', fg='navy', bg='lemon chiffon') self.grd_lbl.place(x=lblx, y=objy, height=objh, width=lblw)
self.grd_val = Label(self.res_fr, text=' ', anchor=E, padx = 3, font='"Noto Mono" 12 bold', fg='navy', bg='lemon chiffon') self.grd_val.place(x=valx, y=objy, height=objh, width=valw)
objy = objy + objh # next row self.mil_lbl = Label(self.res_fr, text=' mils: ', anchor=E, font='"Noto Mono" 12 bold', fg='navy', bg='lemon chiffon') self.mil_lbl.place(x=lblx, y=objy, height=objh, width=lblw) self.mil_val = Label(self.res_fr, text=' ', anchor=E, padx = 3, font='"Noto Mono" 12 bold', fg='navy', bg='lemon chiffon') self.mil_val.place(x=valx, y=objy, height=objh, width=valw)
objy = objy + objh # next row self.rad_lbl = Label(self.res_fr, text='radians: ', anchor=E, font='"Noto Mono" 12 bold', fg='navy', bg='lemon chiffon') self.rad_lbl.place(x=lblx, y=objy, height=objh, width=lblw)
self.rad_val = Label(self.res_fr, text=' ', anchor=E, padx = 3, font='"Noto Mono" 12 bold', fg='navy', bg='lemon chiffon') self.rad_val.place(x=valx, y=objy, height=objh, width=valw)
# process conversion request: def convert(self): # edit requested angle and unit: try: a = float(self.nbr_ent.get()) except: self.err_msg('Angle entry must be numeric') return u = self.unit.get() if u not in self.d_to_deg: self.err_msg('Unit must be selected') return # convert request to degrees: deg = self.d_to_deg[u](a)
# normalize: self.deg = self.normalize(deg) # convert to grads, mils, radians self.grad = self.d2g(self.deg) self.mil = self.d2m(self.deg) self.rad = self.d2r(self.deg) # show results self.deg_val.config(text=self.format_angle(self.deg)) self.grd_val.config(text=self.format_angle(self.grad)) self.mil_val.config(text=self.format_angle(self.mil)) self.rad_val.config(text=self.format_angle(self.rad)) return
def d2d(self, a): return a
def g2d(self, a): return .9 * a
def r2d(self, a): return 180 * a / math.pi
def m2d(self, a): return .05625 * a
def normalize(self, a): if a >= 0: x = a % 360 else: x = -(-a % 360) if x == -0.0: x = 0.0 return x def d2g(self, a): return 10 * a / 9
def d2m(self, a): return 160 * a / 9
def d2r(self, a): return math.pi * a / 180
def format_angle(self, a): return f'{a:.4f}' def err_msg(self, msg): messagebox.showerror('Error Message', msg) return
# restore screen to it's 'initial' state: def clear_screen(self): self.nbr_ent.delete(0, 'end') self.unit.set(' ') self.deg_val.config(text=) self.grd_val.config(text=) self.mil_val.config(text=) self.rad_val.config(text=) return def close_window(self): self.window.destroy()
- ************************************************
root = Tk() root.title('ANGLES') root.geometry('600x600+100+50') root.resizable(False, False) a = Angle(root) root.mainloop()
- ************************************************
- I wish I could show a screenshot of the tkinter window
- to show how the input and output appear, but I don't know
- if that is possible here.
- I have processed all of the suggested angles and the
- results matched those from a few other languages on this
- page.
</lang>
Racket
<lang racket>#lang racket
(define (rem n m)
(let* ((m (abs m)) (-m (- m))) (let recur ((n n)) (cond [(< n -m) (recur (+ n m))] [(>= n m) (recur (- n m))] [else n]))))
(define 2.pi (* 2 pi))
(define (deg->deg a) (rem a 360)) (define (grad->grad a) (rem a 400)) (define (mil->mil a) (rem a 6400)) (define (rad->rad a) (rem a 2.pi))
(define (deg->grad a) (grad->grad (* (/ a 360) 400))) (define (deg->rad a) (rad->rad (* (/ a 360) 2.pi))) (define (deg->mil a) (mil->mil (* (/ a 360) 6400)))
(define (grad->deg a) (deg->deg (* (/ a 400) 360))) (define (grad->rad a) (rad->rad (* (/ a 400) 2.pi))) (define (grad->mil a) (mil->mil (* (/ a 400) 6400)))
(define (mil->deg a) (deg->deg (* (/ a 6400) 360))) (define (mil->grad a) (grad->grad (* (/ a 6400) 400))) (define (mil->rad a) (rad->rad (* (/ a 6400) 2.pi)))
(define (rad->deg a) (deg->deg (* (/ a 2.pi) 360))) (define (rad->grad a) (grad->grad (* (/ a 2.pi) 400))) (define (rad->mil a) (mil->mil (* (/ a 2.pi) 6400)))
(define (tabulate #:fmt (fmt (λ (v) (~a (exact->inexact v) #:align 'right #:width 15))) head . vs)
(string-join (cons (~a #:width 6 head) (map fmt vs)) " | "))
(define (report-angle a)
(string-join (list (tabulate #:fmt (λ (x) (~a x #:width 15 #:align 'center)) "UNIT" "VAL*" "DEG" "GRAD" "MIL" "RAD") (tabulate "Deg" a (deg->deg a) (deg->grad a) (deg->mil a) (deg->rad a)) (tabulate "Grad" a (grad->deg a) (grad->grad a) (grad->mil a) (grad->rad a)) (tabulate "Mil" a (mil->deg a) (mil->grad a) (mil->mil a) (mil->rad a)) (tabulate "Rad" a (rad->deg a) (rad->grad a) (rad->mil a) (rad->rad a))) "\n"))
(module+ test
(displayln (string-join (map report-angle '(-2 -1 0 1 2 6.2831853 16 57.2957795 359 399 6399 1000000)) "\n\n")))</lang>
- Output:
UNIT | VAL* | DEG | GRAD | MIL | RAD Deg | -2.0 | -2.0 | -2.222222222222 | -35.55555555555 | -0.034906585039 Grad | -2.0 | -1.8 | -2.0 | -32.0 | -0.031415926535 Mil | -2.0 | -0.1125 | -0.125 | -2.0 | -0.001963495408 Rad | -2.0 | -114.5915590261 | -127.3239544735 | -2037.183271576 | -2.0 UNIT | VAL* | DEG | GRAD | MIL | RAD Deg | -1.0 | -1.0 | -1.111111111111 | -17.77777777777 | -0.017453292519 Grad | -1.0 | -0.9 | -1.0 | -16.0 | -0.015707963267 Mil | -1.0 | -0.05625 | -0.0625 | -1.0 | -0.000981747704 Rad | -1.0 | -57.29577951308 | -63.66197723675 | -1018.591635788 | -1.0 UNIT | VAL* | DEG | GRAD | MIL | RAD Deg | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 Grad | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 Mil | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 Rad | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 UNIT | VAL* | DEG | GRAD | MIL | RAD Deg | 1.0 | 1.0 | 1.1111111111111 | 17.777777777777 | 0.0174532925199 Grad | 1.0 | 0.9 | 1.0 | 16.0 | 0.0157079632679 Mil | 1.0 | 0.05625 | 0.0625 | 1.0 | 0.0009817477042 Rad | 1.0 | 57.295779513082 | 63.661977236758 | 1018.5916357881 | 1.0 UNIT | VAL* | DEG | GRAD | MIL | RAD Deg | 2.0 | 2.0 | 2.2222222222222 | 35.555555555555 | 0.0349065850398 Grad | 2.0 | 1.8 | 2.0 | 32.0 | 0.0314159265358 Mil | 2.0 | 0.1125 | 0.125 | 2.0 | 0.0019634954084 Rad | 2.0 | 114.59155902616 | 127.32395447351 | 2037.1832715762 | 2.0 UNIT | VAL* | DEG | GRAD | MIL | RAD Deg | 6.2831853 | 6.2831853 | 6.9813170000000 | 111.70107200000 | 0.1096622709979 Grad | 6.2831853 | 5.6548667700000 | 6.2831853 | 100.5309648 | 0.0986960438981 Mil | 6.2831853 | 0.3534291731250 | 0.39269908125 | 6.2831853 | 0.0061685027436 Rad | 6.2831853 | 359.99999958864 | 399.99999954293 | 6399.9999926869 | 6.2831853 UNIT | VAL* | DEG | GRAD | MIL | RAD Deg | 16.0 | 16.0 | 17.777777777777 | 284.44444444444 | 0.2792526803190 Grad | 16.0 | 14.4 | 16.0 | 256.0 | 0.2513274122871 Mil | 16.0 | 0.9 | 1.0 | 16.0 | 0.0157079632679 Rad | 16.0 | 196.73247220931 | 218.59163578813 | 3497.4661726100 | 3.4336293856408 UNIT | VAL* | DEG | GRAD | MIL | RAD Deg | 57.2957795 | 57.2957795 | 63.661977222222 | 1018.5916355555 | 0.9999999997716 Grad | 57.2957795 | 51.56620155 | 57.2957795 | 916.732472 | 0.8999999997945 Mil | 57.2957795 | 3.222887596875 | 3.58098621875 | 57.2957795 | 0.0562499999871 Rad | 57.2957795 | 42.806349262182 | 47.562610291313 | 761.00176466102 | 0.7471117353837 UNIT | VAL* | DEG | GRAD | MIL | RAD Deg | 359.0 | 359.0 | 398.88888888888 | 6382.2222222222 | 6.2657320146596 Grad | 359.0 | 323.1 | 359.0 | 5744.0 | 5.6391588131936 Mil | 359.0 | 20.19375 | 22.4375 | 359.0 | 0.3524474258246 Rad | 359.0 | 49.184845196556 | 54.649827996174 | 874.39724793878 | 0.8584374907637 UNIT | VAL* | DEG | GRAD | MIL | RAD Deg | 399.0 | 39.0 | 43.333333333333 | 693.33333333333 | 0.6806784082777 Grad | 399.0 | 359.1 | 399.0 | 6384.0 | 6.2674773439116 Mil | 399.0 | 22.44375 | 24.9375 | 399.0 | 0.3917173339944 Rad | 399.0 | 181.01602571984 | 201.12891746649 | 3218.0626794639 | 3.1593256476863 UNIT | VAL* | DEG | GRAD | MIL | RAD Deg | 6399.0 | 279.0 | 310.0 | 4960.0 | 4.8694686130641 Grad | 6399.0 | 359.1 | 399.0 | 6384.0 | 6.2674773439116 Mil | 6399.0 | 359.94375 | 399.9375 | 6399.0 | 6.2822035594753 Rad | 6399.0 | 155.69310421380 | 172.99233801534 | 2767.8774082455 | 2.7173572912109 UNIT | VAL* | DEG | GRAD | MIL | RAD Deg | 1000000.0 | 280.0 | 311.11111111111 | 4977.7777777777 | 4.8869219047104 Grad | 1000000.0 | 0.0 | 0.0 | 0.0 | 6.2831853064904 Mil | 1000000.0 | 90.0 | 100.0 | 1600.0 | 1.5707963267971 Rad | 1000000.0 | 339.51308232545 | 377.23675813525 | 6035.7881301641 | 5.9256225262850
Raku
(formerly Perl 6) <lang perl6> my @units =
{ code => 'd', name => 'degrees' , number => 360 }, { code => 'g', name => 'gradians', number => 400 }, { code => 'm', name => 'mills' , number => 6400 }, { code => 'r', name => 'radians' , number => tau },
my Code %cvt = (@units X @units).map: -> ($a, $b) {
"{$a.}2{$b.}" => sub ($angle) {
my $norm = $angle % $a.<number>
- ( $a.<number> if $angle < 0 );
$norm * $b.<number> / $a.<number>
}
}
say ' Angle Unit ', @units».<name>».tc.fmt('%11s');
for -2, -1, 0, 1, 2, tau, 16, 360/tau, 360-1, 400-1, 6400-1, 1_000_000 -> $angle {
say ;
for @units -> $from {
my @sub_keys = @units.map: { "{$from.}2{.}" };
my @results = %cvt{@sub_keys}».($angle);
say join ' ', $angle .fmt('%10g'),
$from.<name>.fmt('%-8s'),
@results .fmt('%11g');
}
}</lang>
- Output:
Angle Unit Degrees Gradians Mills Radians
-2 degrees -2 -2.22222 -35.5556 -0.0349066
-2 gradians -1.8 -2 -32 -0.0314159
-2 mills -0.1125 -0.125 -2 -0.0019635
-2 radians -114.592 -127.324 -2037.18 -2
-1 degrees -1 -1.11111 -17.7778 -0.0174533
-1 gradians -0.9 -1 -16 -0.015708
-1 mills -0.05625 -0.0625 -1 -0.000981748
-1 radians -57.2958 -63.662 -1018.59 -1
0 degrees 0 0 0 0
0 gradians 0 0 0 0
0 mills 0 0 0 0
0 radians 0 0 0 0
1 degrees 1 1.11111 17.7778 0.0174533
1 gradians 0.9 1 16 0.015708
1 mills 0.05625 0.0625 1 0.000981748
1 radians 57.2958 63.662 1018.59 1
2 degrees 2 2.22222 35.5556 0.0349066
2 gradians 1.8 2 32 0.0314159
2 mills 0.1125 0.125 2 0.0019635
2 radians 114.592 127.324 2037.18 2
6.28319 degrees 6.28319 6.98132 111.701 0.109662
6.28319 gradians 5.65487 6.28319 100.531 0.098696
6.28319 mills 0.353429 0.392699 6.28319 0.0061685
6.28319 radians 0 0 0 0
16 degrees 16 17.7778 284.444 0.279253
16 gradians 14.4 16 256 0.251327
16 mills 0.9 1 16 0.015708
16 radians 196.732 218.592 3497.47 3.43363
57.2958 degrees 57.2958 63.662 1018.59 1
57.2958 gradians 51.5662 57.2958 916.732 0.9
57.2958 mills 3.22289 3.58099 57.2958 0.05625
57.2958 radians 42.8064 47.5626 761.002 0.747112
359 degrees 359 398.889 6382.22 6.26573
359 gradians 323.1 359 5744 5.63916
359 mills 20.1938 22.4375 359 0.352447
359 radians 49.1848 54.6498 874.397 0.858437
399 degrees 39 43.3333 693.333 0.680678
399 gradians 359.1 399 6384 6.26748
399 mills 22.4438 24.9375 399 0.391717
399 radians 181.016 201.129 3218.06 3.15933
6399 degrees 279 310 4960 4.86947
6399 gradians 359.1 399 6384 6.26748
6399 mills 359.944 399.938 6399 6.2822
6399 radians 155.693 172.992 2767.88 2.71736
1000000 degrees 280 311.111 4977.78 4.88692
1000000 gradians 0 0 0 0
1000000 mills 90 100 1600 1.5708
1000000 radians 339.513 377.237 6035.79 5.92562
Alternately, implemented as a series of postfix operators:
(Much of the complexity is due to the requirement that negative angles must normalize to a negative number.)
<lang perl6>sub postfix:<t>( $t ) { my $a = $t % 1 * τ; $t >=0 ?? $a !! $a - τ }
sub postfix:<d>( $d ) { my $a = $d % 360 * τ / 360; $d >=0 ?? $a !! $a - τ }
sub postfix:<g>( $g ) { my $a = $g % 400 * τ / 400; $g >=0 ?? $a !! $a - τ }
sub postfix:<m>( $m ) { my $a = $m % 6400 * τ / 6400; $m >=0 ?? $a !! $a - τ }
sub postfix:<r>( $r ) { my $a = $r % τ; $r >=0 ?? $a !! $a - τ }
sub postfix:«->t» ($angle) { my $a = $angle / τ; ($angle < 0 and $a == -1) ?? -0 !! $a }
sub postfix:«->d» ($angle) { my $a = $angle / τ * 360; ($angle < 0 and $a == -360) ?? -0 !! $a }
sub postfix:«->g» ($angle) { my $a = $angle / τ * 400; ($angle < 0 and $a == -400) ?? -0 !! $a }
sub postfix:«->m» ($angle) { my $a = $angle / τ * 6400; ($angle < 0 and $a == -6400) ?? -0 !! $a }
sub postfix:«->r» ($angle) { my $a = $angle; ($angle < 0 and $a == -τ) ?? -0 !! $a }
for <-2 -1 0 1 2 6.2831853 16 57.2957795 359 399 6399 1000000> -> $a {
say ;
say ' Quantity Unit ', <turns degrees gradians mils radians>.fmt('%15s');
for 'turns', &postfix:«t», 'degrees', &postfix:«d», 'gradians', &postfix:«g»,
'mils', &postfix:«m», 'radians', &postfix:«r»
-> $unit, &f {
printf "%10s %-10s %15s %15s %15s %15s %15s\n", $a, $unit,
|($a.&f->t, $a.&f->d, $a.&f->g, $a.&f->m, $a.&f->r)».round(.00000001);
}
}</lang>
Quantity Unit turns degrees gradians mils radians
-2 turns 0 0 0 0 0
-2 degrees -0.00555556 -2 -2.22222222 -35.55555556 -0.03490659
-2 gradians -0.005 -1.8 -2 -32 -0.03141593
-2 mils -0.000313 -0.1125 -0.125 -2 -0.0019635
-2 radians -0.31830989 -114.59155903 -127.32395447 -2037.18327158 -2
Quantity Unit turns degrees gradians mils radians
-1 turns 0 0 0 0 0
-1 degrees -0.00277778 -1 -1.11111111 -17.77777778 -0.01745329
-1 gradians -0.0025 -0.9 -1 -16 -0.01570796
-1 mils -0.000156 -0.05625 -0.0625 -1 -0.00098175
-1 radians -0.15915494 -57.29577951 -63.66197724 -1018.59163579 -1
Quantity Unit turns degrees gradians mils radians
0 turns 0 0 0 0 0
0 degrees 0 0 0 0 0
0 gradians 0 0 0 0 0
0 mils 0 0 0 0 0
0 radians 0 0 0 0 0
Quantity Unit turns degrees gradians mils radians
1 turns 0 0 0 0 0
1 degrees 0.00277778 1 1.11111111 17.77777778 0.01745329
1 gradians 0.0025 0.9 1 16 0.01570796
1 mils 0.000156 0.05625 0.0625 1 0.00098175
1 radians 0.15915494 57.29577951 63.66197724 1018.59163579 1
Quantity Unit turns degrees gradians mils radians
2 turns 0 0 0 0 0
2 degrees 0.00555556 2 2.22222222 35.55555556 0.03490659
2 gradians 0.005 1.8 2 32 0.03141593
2 mils 0.000313 0.1125 0.125 2 0.0019635
2 radians 0.31830989 114.59155903 127.32395447 2037.18327158 2
Quantity Unit turns degrees gradians mils radians
6.2831853 turns 0.2831853 101.946708 113.27412 1812.38592 1.77930572
6.2831853 degrees 0.01745329 6.2831853 6.981317 111.701072 0.10966227
6.2831853 gradians 0.01570796 5.65486677 6.2831853 100.5309648 0.09869604
6.2831853 mils 0.00098175 0.35342917 0.39269908 6.2831853 0.0061685
6.2831853 radians 1 359.99999959 399.99999954 6399.99999269 6.2831853
Quantity Unit turns degrees gradians mils radians
16 turns 0 0 0 0 0
16 degrees 0.04444444 16 17.77777778 284.44444444 0.27925268
16 gradians 0.04 14.4 16 256 0.25132741
16 mils 0.0025 0.9 1 16 0.01570796
16 radians 0.54647909 196.73247221 218.59163579 3497.46617261 3.43362939
Quantity Unit turns degrees gradians mils radians
57.2957795 turns 0.2957795 106.48062 118.3118 1892.9888 1.85843741
57.2957795 degrees 0.15915494 57.2957795 63.66197722 1018.59163556 1
57.2957795 gradians 0.14323945 51.56620155 57.2957795 916.732472 0.9
57.2957795 mils 0.00895247 3.2228876 3.58098622 57.2957795 0.05625
57.2957795 radians 0.11890653 42.80634926 47.56261029 761.00176466 0.74711174
Quantity Unit turns degrees gradians mils radians
359 turns 0 0 0 0 0
359 degrees 0.99722222 359 398.88888889 6382.22222222 6.26573201
359 gradians 0.8975 323.1 359 5744 5.63915881
359 mils 0.056094 20.19375 22.4375 359 0.35244743
359 radians 0.13662457 49.1848452 54.649828 874.39724794 0.85843749
Quantity Unit turns degrees gradians mils radians
399 turns 0 0 0 0 0
399 degrees 0.10833333 39 43.33333333 693.33333333 0.68067841
399 gradians 0.9975 359.1 399 6384 6.26747734
399 mils 0.062344 22.44375 24.9375 399 0.39171733
399 radians 0.50282229 181.01602572 201.12891747 3218.06267946 3.15932565
Quantity Unit turns degrees gradians mils radians
6399 turns 0 0 0 0 0
6399 degrees 0.775 279 310 4960 4.86946861
6399 gradians 0.9975 359.1 399 6384 6.26747734
6399 mils 0.999844 359.94375 399.9375 6399 6.28220356
6399 radians 0.43248085 155.69310421 172.99233802 2767.87740825 2.71735729
Quantity Unit turns degrees gradians mils radians
1000000 turns 0 0 0 0 0
1000000 degrees 0.77777778 280 311.11111111 4977.77777778 4.88692191
1000000 gradians 0 0 0 0 0
1000000 mils 0.25 90 100 1600 1.57079633
1000000 radians 0.9430919 339.51308233 377.23675814 6035.78813022 5.92562114
REXX
<lang rexx>/*REXX pgm normalizes an angle (in a scale), or converts angles from a scale to another.*/
numeric digits length( pi() ) - length(.) /*use the "length" of pi for precision.*/
parse arg x /*obtain optional arguments from the CL*/
if x= | x="," then x= '-2 -1 0 1 2 6.2831853 16 57.2957795 359 399 6399 1000000'
w= 20; w7= w+7 /*W: # dec digits past the dec. point.*/
@deg = 'degrees'; @grd= "gradians"; @mil = 'mils'; @rad = "radians"
- = words(x)
call hdr @deg @grd @mil @rad
do j=1 for #; y= word(x,j)
say shw(y) fmt(d2d(y)) fmt(d2g(y)) fmt(d2m(y)) fmt(d2r(y))
end /*j*/
call hdr @grd @deg @mil @rad
do j=1 for #; y= word(x,j)
say shw(y) fmt(g2g(y)) fmt(g2d(y)) fmt(g2m(y)) fmt(g2r(y))
end /*j*/
call hdr @mil @deg @grd @rad
do j=1 for #; y= word(x,j)
say shw(y) fmt(m2m(y)) fmt(m2d(y)) fmt(m2g(y)) fmt(m2r(y))
end /*j*/
call hdr @rad @deg @grd @mil
do j=1 for #; y= word(x,j)
say shw(y) fmt(r2r(y)) fmt(r2d(y)) fmt(r2g(y)) fmt(r2m(y))
end /*j*/
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
fmt: _= format(arg(1), 6,w); L= length(_); return left(format(_/1, 6),L) /*align a #*/
shw: _= format(arg(1),12,9); L= length(_); return left(format(_/1,12),L) /* " " "*/
pi: pi= 3.1415926535897932384626433832795028841971693993751058209749445923078; return pi
d2g: return d2d(arg(1)) * 10 / 9 /*convert degrees ───► gradians. */
d2m: return d2d(arg(1)) * 160 / 9 /*convert degrees ───► mils. */
d2r: return d2d(arg(1)) * pi() / 180 /*convert degrees ───► radians. */
g2d: return g2g(arg(1)) * 0.9 /*convert gradians ───► degrees. */
g2m: return g2g(arg(1)) * 16 /*convert gradians ───► mils. */
g2r: return g2g(arg(1)) * pi() * 0.005 /*convert gradians ───► radians. */
m2d: return m2m(arg(1)) * 9 * 0.00625 /*convert mils ───► degrees. */
m2g: return m2m(arg(1)) / 16 /*convert mils ───► gradians. */
m2r: return m2m(arg(1)) * pi() / 3200 /*convert mils ───► radians. */
r2d: return r2r(arg(1)) * 180 / pi() /*convert radians ───► degrees. */
r2g: return r2r(arg(1)) * 200 / pi() /*convert radians ───► gradians. */
r2m: return r2r(arg(1)) * 3200 / pi() /*convert radians ───► mils. */
d2d: return arg(1) // 360 /*normalize degrees ───► a unit circle.*/
g2g: return arg(1) // 400 /*normalize gradians───► a unit circle.*/
m2m: return arg(1) // 6400 /*normalize mils ───► a unit circle.*/
r2r: return arg(1) // (pi() * 2) /*normalize radians ───► a unit circle.*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
hdr: parse arg #o #a #b #c .; _= '═'; say /* [↓] the header line*/
@n = 'normalized'
say center(#o,23 ) center(@n #o,w7) center(#a,w7 ) center(#b,w7 ) center(#c,w7 )
say center(,23,_) center(,w7, _) center(,w7,_) center(,w7,_) center(,w7,_)
return /* '↑' seperator line.*/</lang>
- output when using the default input:
degrees normalized degrees gradians mils radians
═══════════════════════ ═══════════════════════════ ═══════════════════════════ ═══════════════════════════ ═══════════════════════════
-2 -2 -2.22222222222222222222 -35.55555555555555555556 -0.03490658503988659154
-1 -1 -1.11111111111111111111 -17.77777777777777777778 -0.01745329251994329577
0 0 0 0 0
1 1 1.11111111111111111111 17.77777777777777777778 0.01745329251994329577
2 2 2.22222222222222222222 35.55555555555555555556 0.03490658503988659154
6.2831853 6.2831853 6.981317 111.701072 0.10966227099790767281
16 16 17.77777777777777777778 284.44444444444444444444 0.27925268031909273231
57.2957795 57.2957795 63.66197722222222222222 1018.59163555555555555556 0.9999999997716704269
359 359 398.88888888888888888889 6382.22222222222222222222 6.26573201465964318116
399 39 43.33333333333333333333 693.33333333333333333333 0.680678408277788535
6399 279 310 4960 4.86946861306417951962
1000000 280 311.11111111111111111111 4977.77777777777777777778 4.88692190558412281539
gradians normalized gradians degrees mils radians
═══════════════════════ ═══════════════════════════ ═══════════════════════════ ═══════════════════════════ ═══════════════════════════
-2 -2 -1.8 -32 -0.03141592653589793238
-1 -1 -0.9 -16 -0.01570796326794896619
0 0 0 0 0
1 1 0.9 16 0.01570796326794896619
2 2 1.8 32 0.03141592653589793238
6.2831853 6.2831853 5.65486677 100.5309648 0.09869604389811690553
16 16 14.4 256 0.25132741228718345908
57.2957795 57.2957795 51.56620155 916.732472 0.89999999979450338421
359 359 323.1 5744 5.63915881319367886304
399 399 359.1 6384 6.26747734391163751073
6399 399 359.1 6384 6.26747734391163751073
1000000 0 0 0 0
mils normalized mils degrees gradians radians
═══════════════════════ ═══════════════════════════ ═══════════════════════════ ═══════════════════════════ ═══════════════════════════
-2 -2 -0.1125 -0.125 -0.00196349540849362077
-1 -1 -0.05625 -0.0625 -0.00098174770424681039
0 0 0 0 0
1 1 0.05625 0.0625 0.00098174770424681039
2 2 0.1125 0.125 0.00196349540849362077
6.2831853 6.2831853 0.353429173125 0.39269908125 0.0061685027436323066
16 16 0.9 1 0.01570796326794896619
57.2957795 57.2957795 3.222887596875 3.58098621875 0.05624999998715646151
359 359 20.19375 22.4375 0.35244742582460492894
399 399 22.44375 24.9375 0.39171733399447734442
6399 6399 359.94375 399.9375 6.28220355947533966654
1000000 1600 90 100 1.57079632679489661923
radians normalized radians degrees gradians mils
═══════════════════════ ═══════════════════════════ ═══════════════════════════ ═══════════════════════════ ═══════════════════════════
-2 -2 -114.5915590261646417536 -127.32395447351626861511 -2037.18327157626029784171
-1 -1 -57.2957795130823208768 -63.66197723675813430755 -1018.59163578813014892086
0 0 0 0 0
1 1 57.2957795130823208768 63.66197723675813430755 1018.59163578813014892086
2 2 114.5915590261646417536 127.32395447351626861511 2037.18327157626029784171
6.2831853 6.2831853 359.99999958863999622298 399.99999954293332913665 6399.99999268693326618633
16 3.43362938564082704615 196.73247220931713402877 218.59163578813014892086 3497.4661726100823827337
57.2957795 0.74711173538372170767 42.80634926218202230527 47.56261029131335811697 761.00176466101372987153
359 0.85843749076357081526 49.18484519655319477054 54.64982799617021641171 874.39724793872346258733
399 3.15932564768605195371 181.01602571984602984246 201.12891746649558871385 3218.06267946392941942158
6399 2.71735729118096649006 155.69310421377129063139 172.99233801530143403488 2767.87740824482294455809
1000000 5.92562114009385143291 339.51308232087679815481 377.23675813430755350535 6035.78813014892085608558
Ruby
This Angles module responds to methods like r2d. Adding an element (like "h"=>24, for a clock-like angle system) to the BASES hash adds 9 more methods, totaling to 25 methods. None of these methods are actually implemented.
<lang ruby>module Angles
BASES = {"d" => 360, "g" => 400, "m" => 6400, "r" => Math::PI*2 ,"h" => 24 }
def self.method_missing(meth, angle)
from, to = BASES.values_at(*meth.to_s.split("2"))
raise NoMethodError, meth if (from.nil? or to.nil?)
mod = (angle.to_f * to / from) % to
angle < 0 ? mod - to : mod
end
end
- Demo
names = Angles::BASES.keys
puts " " + "%12s "*names.size % names
test = [-2, -1, 0, 1, 2*Math::PI, 16, 360/(2*Math::PI), 360-1, 400-1, 6400-1, 1_000_000]
test.each do |n|
names.each do |first|
res = names.map{|last| Angles.send((first + "2" + last).to_sym, n)}
puts first + "%12g "*names.size % res
end
puts
end
</lang>
- Output:
d g m r h
d -2 -2.22222 -35.5556 -0.0349066 -0.133333
g -1.8 -2 -32 -0.0314159 -0.12
m -0.1125 -0.125 -2 -0.0019635 -0.0075
r -114.592 -127.324 -2037.18 -2 -7.63944
h -30 -33.3333 -533.333 -0.523599 -2
d -1 -1.11111 -17.7778 -0.0174533 -0.0666667
g -0.9 -1 -16 -0.015708 -0.06
m -0.05625 -0.0625 -1 -0.000981748 -0.00375
r -57.2958 -63.662 -1018.59 -1 -3.81972
h -15 -16.6667 -266.667 -0.261799 -1
d 0 0 0 0 0
g 0 0 0 0 0
m 0 0 0 0 0
r 0 0 0 0 0
h 0 0 0 0 0
d 1 1.11111 17.7778 0.0174533 0.0666667
g 0.9 1 16 0.015708 0.06
m 0.05625 0.0625 1 0.000981748 0.00375
r 57.2958 63.662 1018.59 1 3.81972
h 15 16.6667 266.667 0.261799 1
d 6.28319 6.98132 111.701 0.109662 0.418879
g 5.65487 6.28319 100.531 0.098696 0.376991
m 0.353429 0.392699 6.28319 0.0061685 0.0235619
r 0 0 0 0 0
h 94.2478 104.72 1675.52 1.64493 6.28319
d 16 17.7778 284.444 0.279253 1.06667
g 14.4 16 256 0.251327 0.96
m 0.9 1 16 0.015708 0.06
r 196.732 218.592 3497.47 3.43363 13.1155
h 240 266.667 4266.67 4.18879 16
d 57.2958 63.662 1018.59 1 3.81972
g 51.5662 57.2958 916.732 0.9 3.43775
m 3.22289 3.58099 57.2958 0.05625 0.214859
r 42.8064 47.5626 761.002 0.747112 2.85376
h 139.437 154.93 2478.87 2.43363 9.29578
d 359 398.889 6382.22 6.26573 23.9333
g 323.1 359 5744 5.63916 21.54
m 20.1938 22.4375 359 0.352447 1.34625
r 49.1848 54.6498 874.397 0.858437 3.27899
h 345 383.333 6133.33 6.02139 23
d 39 43.3333 693.333 0.680678 2.6
g 359.1 399 6384 6.26748 23.94
m 22.4438 24.9375 399 0.391717 1.49625
r 181.016 201.129 3218.06 3.15933 12.0677
h 225 250 4000 3.92699 15
d 279 310 4960 4.86947 18.6
g 359.1 399 6384 6.26748 23.94
m 359.944 399.938 6399 6.2822 23.9962
r 155.693 172.992 2767.88 2.71736 10.3795
h 225 250 4000 3.92699 15
d 280 311.111 4977.78 4.88692 18.6667
g 0 0 0 3.69482e-13 0
m 90 100 1600 1.5708 6
r 339.513 377.237 6035.79 5.92562 22.6342
h 240 266.667 4266.67 4.18879 16
Rust
<lang rust>use std::{
marker::PhantomData,
f64::consts::PI,
};
pub trait AngleUnit: Copy {
const TURN: f64;
const NAME: &'static str;
}
macro_rules! unit {
($name:ident, $value:expr, $string:expr) => (
#[derive(Debug, Copy, Clone)]
struct $name;
impl AngleUnit for $name {
const TURN: f64 = $value;
const NAME: &'static str = $string;
}
);
}
unit!(Degrees, 360.0, "Degrees");
unit!(Radians, PI * 2.0, "Radians");
unit!(Gradians, 400.0, "Gradians");
unit!(Mils, 6400.0, "Mils");
- [derive(Copy, Clone, PartialEq, PartialOrd)]
struct Angle<T: AngleUnit>(f64, PhantomData<T>);
impl<T: AngleUnit> Angle<T> {
pub fn new(val: f64) -> Self {
Self(val, PhantomData)
}
pub fn normalize(self) -> Self {
Self(self.0 % T::TURN, PhantomData)
}
pub fn val(self) -> f64 {
self.0
}
pub fn convert<U: AngleUnit>(self) -> Angle {
Angle::new(self.0 * U::TURN / T::TURN)
}
pub fn name(self) -> &'static str {
T::NAME
}
}
fn print_angles<T: AngleUnit>() {
let angles = [-2.0, -1.0, 0.0, 1.0, 2.0, 6.2831853, 16.0, 57.2957795, 359.0, 399.0, 6399.0, 1000000.0];
println!("{:<12} {:<12} {:<12} {:<12} {:<12} {:<12}", "Angle", "Unit", "Degrees", "Gradians", "Mils", "Radians");
for &angle in &angles {
let deg = Angle::<T>::new(angle).normalize();
println!("{:<12} {:<12} {:<12.4} {:<12.4} {:<12.4} {:<12.4}",
angle,
deg.name(),
deg.convert::<Degrees>().val(),
deg.convert::<Gradians>().val(),
deg.convert::<Mils>().val(),
deg.convert::<Radians>().val(),
);
}
println!();
}
fn main() {
print_angles::<Degrees>();
print_angles::<Gradians>();
print_angles::<Mils>();
print_angles::<Radians>();
}</lang>
- Output:
Angle Unit Degrees Gradians Mils Radians
-2 Degrees -2.0000 -2.2222 -35.5556 -0.0349
-1 Degrees -1.0000 -1.1111 -17.7778 -0.0175
0 Degrees 0.0000 0.0000 0.0000 0.0000
1 Degrees 1.0000 1.1111 17.7778 0.0175
2 Degrees 2.0000 2.2222 35.5556 0.0349
6.2831853 Degrees 6.2832 6.9813 111.7011 0.1097
16 Degrees 16.0000 17.7778 284.4444 0.2793
57.2957795 Degrees 57.2958 63.6620 1018.5916 1.0000
359 Degrees 359.0000 398.8889 6382.2222 6.2657
399 Degrees 39.0000 43.3333 693.3333 0.6807
6399 Degrees 279.0000 310.0000 4960.0000 4.8695
1000000 Degrees 280.0000 311.1111 4977.7778 4.8869
Angle Unit Degrees Gradians Mils Radians
-2 Gradians -1.8000 -2.0000 -32.0000 -0.0314
-1 Gradians -0.9000 -1.0000 -16.0000 -0.0157
0 Gradians 0.0000 0.0000 0.0000 0.0000
1 Gradians 0.9000 1.0000 16.0000 0.0157
2 Gradians 1.8000 2.0000 32.0000 0.0314
6.2831853 Gradians 5.6549 6.2832 100.5310 0.0987
16 Gradians 14.4000 16.0000 256.0000 0.2513
57.2957795 Gradians 51.5662 57.2958 916.7325 0.9000
359 Gradians 323.1000 359.0000 5744.0000 5.6392
399 Gradians 359.1000 399.0000 6384.0000 6.2675
6399 Gradians 359.1000 399.0000 6384.0000 6.2675
1000000 Gradians 0.0000 0.0000 0.0000 0.0000
Angle Unit Degrees Gradians Mils Radians
-2 Mils -0.1125 -0.1250 -2.0000 -0.0020
-1 Mils -0.0563 -0.0625 -1.0000 -0.0010
0 Mils 0.0000 0.0000 0.0000 0.0000
1 Mils 0.0563 0.0625 1.0000 0.0010
2 Mils 0.1125 0.1250 2.0000 0.0020
6.2831853 Mils 0.3534 0.3927 6.2832 0.0062
16 Mils 0.9000 1.0000 16.0000 0.0157
57.2957795 Mils 3.2229 3.5810 57.2958 0.0562
359 Mils 20.1938 22.4375 359.0000 0.3524
399 Mils 22.4438 24.9375 399.0000 0.3917
6399 Mils 359.9438 399.9375 6399.0000 6.2822
1000000 Mils 90.0000 100.0000 1600.0000 1.5708
Angle Unit Degrees Gradians Mils Radians
-2 Radians -114.5916 -127.3240 -2037.1833 -2.0000
-1 Radians -57.2958 -63.6620 -1018.5916 -1.0000
0 Radians 0.0000 0.0000 0.0000 0.0000
1 Radians 57.2958 63.6620 1018.5916 1.0000
2 Radians 114.5916 127.3240 2037.1833 2.0000
6.2831853 Radians 360.0000 400.0000 6400.0000 6.2832
16 Radians 196.7325 218.5916 3497.4662 3.4336
57.2957795 Radians 42.8063 47.5626 761.0018 0.7471
359 Radians 49.1848 54.6498 874.3972 0.8584
399 Radians 181.0160 201.1289 3218.0627 3.1593
6399 Radians 155.6931 172.9923 2767.8774 2.7174
1000000 Radians 339.5131 377.2368 6035.7881 5.9256
Swift
<lang swift>import Foundation
func normalize(_ f: Double, N: Double) -> Double {
var a = f
while a < -N { a += N }
while a >= N { a -= N }
return a
}
func normalizeToDeg(_ f: Double) -> Double {
return normalize(f, N: 360)
}
func normalizeToGrad(_ f: Double) -> Double {
return normalize(f, N: 400)
}
func normalizeToMil(_ f: Double) -> Double {
return normalize(f, N: 6400)
}
func normalizeToRad(_ f: Double) -> Double {
return normalize(f, N: 2 * .pi)
}
func d2g(_ f: Double) -> Double { f * 10 / 9 }
func d2m(_ f: Double) -> Double { f * 160 / 9 }
func d2r(_ f: Double) -> Double { f * .pi / 180 }
func g2d(_ f: Double) -> Double { f * 9 / 10 }
func g2m(_ f: Double) -> Double { f * 16 }
func g2r(_ f: Double) -> Double { f * .pi / 200 }
func m2d(_ f: Double) -> Double { f * 9 / 160 }
func m2g(_ f: Double) -> Double { f / 16 }
func m2r(_ f: Double) -> Double { f * .pi / 3200 }
func r2d(_ f: Double) -> Double { f * 180 / .pi }
func r2g(_ f: Double) -> Double { f * 200 / .pi }
func r2m(_ f: Double) -> Double { f * 3200 / .pi }
let angles = [-2, -1, 0, 1, 2, 6.2831853, 16, 57.2957795, 359, 6399, 1_000_000]
let names = ["Degrees", "Gradians", "Mils", "Radians"]
let fmt = { String(format: "%.4f", $0) }
let normal = [normalizeToDeg, normalizeToGrad, normalizeToMil, normalizeToRad]
let convert = [
[{ $0 }, d2g, d2m, d2r],
[g2d, { $0 }, g2m, g2r],
[m2d, m2g, { $0 }, m2r],
[r2d, r2g, r2m, { $0 }]
]
let ans =
angles.map({ angle in
(0..<4).map({ ($0, normal[$0](angle)) }).map({
(fmt(angle),
fmt($0.1),
names[$0.0],
fmt(convert[$0.0][0]($0.1)),
fmt(convert[$0.0][1]($0.1)),
fmt(convert[$0.0][2]($0.1)),
fmt(convert[$0.0][3]($0.1))
)
})
})
print("angle", "normalized", "unit", "degrees", "grads", "mils", "radians")
for res in ans {
for unit in res {
print(unit)
}
print()
}</lang>
- Output:
angle normalized unit degrees grads mils radians
("-2.0000", "-2.0000", "Degrees", "-2.0000", "-2.2222", "-35.5556", "-0.0349")
("-2.0000", "-2.0000", "Gradians", "-1.8000", "-2.0000", "-32.0000", "-0.0314")
("-2.0000", "-2.0000", "Mils", "-0.1125", "-0.1250", "-2.0000", "-0.0020")
("-2.0000", "-2.0000", "Radians", "-114.5916", "-127.3240", "-2037.1833", "-2.0000")
("-1.0000", "-1.0000", "Degrees", "-1.0000", "-1.1111", "-17.7778", "-0.0175")
("-1.0000", "-1.0000", "Gradians", "-0.9000", "-1.0000", "-16.0000", "-0.0157")
("-1.0000", "-1.0000", "Mils", "-0.0563", "-0.0625", "-1.0000", "-0.0010")
("-1.0000", "-1.0000", "Radians", "-57.2958", "-63.6620", "-1018.5916", "-1.0000")
("0.0000", "0.0000", "Degrees", "0.0000", "0.0000", "0.0000", "0.0000")
("0.0000", "0.0000", "Gradians", "0.0000", "0.0000", "0.0000", "0.0000")
("0.0000", "0.0000", "Mils", "0.0000", "0.0000", "0.0000", "0.0000")
("0.0000", "0.0000", "Radians", "0.0000", "0.0000", "0.0000", "0.0000")
("1.0000", "1.0000", "Degrees", "1.0000", "1.1111", "17.7778", "0.0175")
("1.0000", "1.0000", "Gradians", "0.9000", "1.0000", "16.0000", "0.0157")
("1.0000", "1.0000", "Mils", "0.0563", "0.0625", "1.0000", "0.0010")
("1.0000", "1.0000", "Radians", "57.2958", "63.6620", "1018.5916", "1.0000")
("2.0000", "2.0000", "Degrees", "2.0000", "2.2222", "35.5556", "0.0349")
("2.0000", "2.0000", "Gradians", "1.8000", "2.0000", "32.0000", "0.0314")
("2.0000", "2.0000", "Mils", "0.1125", "0.1250", "2.0000", "0.0020")
("2.0000", "2.0000", "Radians", "114.5916", "127.3240", "2037.1833", "2.0000")
("6.2832", "6.2832", "Degrees", "6.2832", "6.9813", "111.7011", "0.1097")
("6.2832", "6.2832", "Gradians", "5.6549", "6.2832", "100.5310", "0.0987")
("6.2832", "6.2832", "Mils", "0.3534", "0.3927", "6.2832", "0.0062")
("6.2832", "6.2832", "Radians", "360.0000", "400.0000", "6400.0000", "6.2832")
("16.0000", "16.0000", "Degrees", "16.0000", "17.7778", "284.4444", "0.2793")
("16.0000", "16.0000", "Gradians", "14.4000", "16.0000", "256.0000", "0.2513")
("16.0000", "16.0000", "Mils", "0.9000", "1.0000", "16.0000", "0.0157")
("16.0000", "3.4336", "Radians", "196.7325", "218.5916", "3497.4662", "3.4336")
("57.2958", "57.2958", "Degrees", "57.2958", "63.6620", "1018.5916", "1.0000")
("57.2958", "57.2958", "Gradians", "51.5662", "57.2958", "916.7325", "0.9000")
("57.2958", "57.2958", "Mils", "3.2229", "3.5810", "57.2958", "0.0562")
("57.2958", "0.7471", "Radians", "42.8063", "47.5626", "761.0018", "0.7471")
("359.0000", "359.0000", "Degrees", "359.0000", "398.8889", "6382.2222", "6.2657")
("359.0000", "359.0000", "Gradians", "323.1000", "359.0000", "5744.0000", "5.6392")
("359.0000", "359.0000", "Mils", "20.1938", "22.4375", "359.0000", "0.3524")
("359.0000", "0.8584", "Radians", "49.1848", "54.6498", "874.3972", "0.8584")
("6399.0000", "279.0000", "Degrees", "279.0000", "310.0000", "4960.0000", "4.8695")
("6399.0000", "399.0000", "Gradians", "359.1000", "399.0000", "6384.0000", "6.2675")
("6399.0000", "6399.0000", "Mils", "359.9438", "399.9375", "6399.0000", "6.2822")
("6399.0000", "2.7174", "Radians", "155.6931", "172.9923", "2767.8774", "2.7174")
("1000000.0000", "280.0000", "Degrees", "280.0000", "311.1111", "4977.7778", "4.8869")
("1000000.0000", "0.0000", "Gradians", "0.0000", "0.0000", "0.0000", "0.0000")
("1000000.0000", "1600.0000", "Mils", "90.0000", "100.0000", "1600.0000", "1.5708")
("1000000.0000", "5.9256", "Radians", "339.5132", "377.2368", "6035.7895", "5.9256")
Wren
<lang ecmascript>import "/fmt" for Fmt
var d2d = Fn.new { |d| d % 360 }
var g2g = Fn.new { |g| g % 400 }
var m2m = Fn.new { |m| m % 6400 }
var r2r = Fn.new { |r| r % (2*Num.pi) }
var d2g = Fn.new { |d| d2d.call(d) * 400 / 360 }
var d2m = Fn.new { |d| d2d.call(d) * 6400 / 360 }
var d2r = Fn.new { |d| d2d.call(d) * Num.pi / 180 }
var g2d = Fn.new { |g| g2g.call(g) * 360 / 400 }
var g2m = Fn.new { |g| g2g.call(g) * 6400 / 400 }
var g2r = Fn.new { |g| g2g.call(g) * Num.pi / 200 }
var m2d = Fn.new { |m| m2m.call(m) * 360 / 6400 }
var m2g = Fn.new { |m| m2m.call(m) * 400 / 6400 }
var m2r = Fn.new { |m| m2m.call(m) * Num.pi / 3200 }
var r2d = Fn.new { |r| r2r.call(r) * 180 / Num.pi }
var r2g = Fn.new { |r| r2r.call(r) * 200 / Num.pi }
var r2m = Fn.new { |r| r2r.call(r) * 3200 / Num.pi }
var f1 = "$15m $15m $15m $15m $15m"
var f2 = "$15.7g $15.7g $15.7g $15.7g $15.7g"
var angles = [-2, -1, 0, 1, 2, 6.2831853, 16, 57.2957795, 359, 399, 6399, 1000000]
Fmt.print(f1, "degrees", "normalized degs", "gradians", "mils", "radians")
for (a in angles) {
Fmt.print(f2, a, d2d.call(a), d2g.call(a), d2m.call(a), d2r.call(a))
}
f1 = "\n" + f1
Fmt.print(f1, "gradians", "normalized grds", "degrees", "mils", "radians")
for (a in angles) {
Fmt.print(f2, a, g2g.call(a), g2d.call(a), g2m.call(a), g2r.call(a))
}
Fmt.print(f1, "mils", "normalized mils", "degrees", "gradians", "radians")
for (a in angles) {
Fmt.print(f2, a, m2m.call(a), m2d.call(a), m2g.call(a), m2r.call(a))
}
Fmt.print(f1, "radians", "normalized rads", "degrees", "gradians", "mils")
for (a in angles) {
Fmt.print(f2, a, r2r.call(a), r2d.call(a), r2g.call(a), r2m.call(a))
}</lang>
- Output:
degrees normalized degs gradians mils radians
-2.0 -2.0 -2.2222222 -35.5555556 -0.0349066
-1.0 -1.0 -1.1111111 -17.7777778 -0.0174533
0.0 0.0 0.0 0.0 0.0
1.0 1.0 1.1111111 17.7777778 0.0174533
2.0 2.0 2.2222222 35.5555556 0.0349066
6.2831853 6.2831853 6.981317 111.701072 0.1096623
16.0 16.0 17.7777778 284.4444444 0.2792527
57.2957795 57.2957795 63.6619772 1018.5916356 1.0
359.0 359.0 398.8888889 6382.2222222 6.265732
399.0 39.0 43.3333333 693.3333333 0.6806784
6399.0 279.0 310.0 4960.0 4.8694686
1000000.0 280.0 311.1111111 4977.7777778 4.8869219
gradians normalized grds degrees mils radians
-2.0 -2.0 -1.8 -32.0 -0.0314159
-1.0 -1.0 -0.9 -16.0 -0.015708
0.0 0.0 0.0 0.0 0.0
1.0 1.0 0.9 16.0 0.015708
2.0 2.0 1.8 32.0 0.0314159
6.2831853 6.2831853 5.6548668 100.5309648 0.098696
16.0 16.0 14.4 256.0 0.2513274
57.2957795 57.2957795 51.5662016 916.732472 0.9
359.0 359.0 323.1 5744.0 5.6391588
399.0 399.0 359.1 6384.0 6.2674773
6399.0 399.0 359.1 6384.0 6.2674773
1000000.0 0.0 0.0 0.0 0.0
mils normalized mils degrees gradians radians
-2.0 -2.0 -0.1125 -0.125 -0.0019635
-1.0 -1.0 -0.05625 -0.0625 -0.0009817
0.0 0.0 0.0 0.0 0.0
1.0 1.0 0.05625 0.0625 0.0009817
2.0 2.0 0.1125 0.125 0.0019635
6.2831853 6.2831853 0.3534292 0.3926991 0.0061685
16.0 16.0 0.9 1.0 0.015708
57.2957795 57.2957795 3.2228876 3.5809862 0.05625
359.0 359.0 20.19375 22.4375 0.3524474
399.0 399.0 22.44375 24.9375 0.3917173
6399.0 6399.0 359.94375 399.9375 6.2822036
1000000.0 1600.0 90.0 100.0 1.5707963
radians normalized rads degrees gradians mils
-2.0 -2.0 -114.591559 -127.3239545 -2037.1832716
-1.0 -1.0 -57.2957795 -63.6619772 -1018.5916358
0.0 0.0 0.0 0.0 0.0
1.0 1.0 57.2957795 63.6619772 1018.5916358
2.0 2.0 114.591559 127.3239545 2037.1832716
6.2831853 6.2831853 359.9999996 399.9999995 6399.9999927
16.0 3.4336294 196.7324722 218.5916358 3497.4661726
57.2957795 0.7471117 42.8063493 47.5626103 761.0017647
359.0 0.8584375 49.1848452 54.649828 874.3972479
399.0 3.1593256 181.0160257 201.1289175 3218.0626795
6399.0 2.7173573 155.6931042 172.992338 2767.8774082
1000000.0 5.9256211 339.5130823 377.2367581 6035.7881302
zkl
<lang zkl>var [const]
tau=(0.0).pi*2,
units=Dictionary( // code:(name, units in circle)
"d", T("degrees", 360.0), "g",T("gradians",400.0),
"m", T("mills", 6400.0), "r",T("radians", tau) ),
cvtNm="%s-->%s".fmt,
cvt= // "d-->r":fcn(angle){}, "r-->d":fcn(angle){} ...
Walker.cproduct(units.keys,units.keys).pump(Dictionary(),fcn([(a,b)]){
return(cvtNm(a,b), // "d-->r"
'wrap(angle){ angle=angle.toFloat();
u:=units[a][1];
(angle%u)*units[b][1] / u
})
})
- </lang>
<lang zkl>codes:=units.keys;
println(" Angle Unit ",
codes.apply(fcn(k){ units[k][0] }).apply("%11s".fmt).concat(" "));
foreach angle in (T(-2.0,-1, 0, 1, 2, tau, 16, 360.0/tau, 360-1, 400-1, 6400-1, 1_000_000)){
println();
foreach from in (codes){
subKeys:=codes.apply(cvtNm.fp(from)); // ("d-->d","d-->g","d-->m","d-->r")
r:=subKeys.pump(List,'wrap(k){ cvt[k](angle) });
println("%10g %-8s %s".fmt(angle,units[from][0],
r.apply("%12g".fmt).concat(" ")));
}
}</lang>
- Output:
Angle Unit degrees gradians mills radians
-2 degrees -2 -2.22222 -35.5556 -0.0349066
-2 gradians -1.8 -2 -32 -0.0314159
-2 mills -0.1125 -0.125 -2 -0.0019635
-2 radians -114.592 -127.324 -2037.18 -2
-1 degrees -1 -1.11111 -17.7778 -0.0174533
-1 gradians -0.9 -1 -16 -0.015708
-1 mills -0.05625 -0.0625 -1 -0.000981748
-1 radians -57.2958 -63.662 -1018.59 -1
0 degrees 0 0 0 0
0 gradians 0 0 0 0
0 mills 0 0 0 0
0 radians 0 0 0 0
1 degrees 1 1.11111 17.7778 0.0174533
1 gradians 0.9 1 16 0.015708
1 mills 0.05625 0.0625 1 0.000981748
1 radians 57.2958 63.662 1018.59 1
2 degrees 2 2.22222 35.5556 0.0349066
2 gradians 1.8 2 32 0.0314159
2 mills 0.1125 0.125 2 0.0019635
2 radians 114.592 127.324 2037.18 2
6.28319 degrees 6.28319 6.98132 111.701 0.109662
6.28319 gradians 5.65487 6.28319 100.531 0.098696
6.28319 mills 0.353429 0.392699 6.28319 0.0061685
6.28319 radians 0 0 0 0
16 degrees 16 17.7778 284.444 0.279253
16 gradians 14.4 16 256 0.251327
16 mills 0.9 1 16 0.015708
16 radians 196.732 218.592 3497.47 3.43363
57.2958 degrees 57.2958 63.662 1018.59 1
57.2958 gradians 51.5662 57.2958 916.732 0.9
57.2958 mills 3.22289 3.58099 57.2958 0.05625
57.2958 radians 42.8064 47.5626 761.002 0.747112
359 degrees 359 398.889 6382.22 6.26573
359 gradians 323.1 359 5744 5.63916
359 mills 20.1938 22.4375 359 0.352447
359 radians 49.1848 54.6498 874.397 0.858437
399 degrees 39 43.3333 693.333 0.680678
399 gradians 359.1 399 6384 6.26748
399 mills 22.4438 24.9375 399 0.391717
399 radians 181.016 201.129 3218.06 3.15933
6399 degrees 279 310 4960 4.86947
6399 gradians 359.1 399 6384 6.26748
6399 mills 359.944 399.938 6399 6.2822
6399 radians 155.693 172.992 2767.88 2.71736
1e+06 degrees 280 311.111 4977.78 4.88692
1e+06 gradians 0 0 0 0
1e+06 mills 90 100 1600 1.5708
1e+06 radians 339.513 377.237 6035.79 5.92562