I'm working on modernizing Rosetta Code's infrastructure. Starting with communications. Please accept this time-limited open invite to RC's Slack.. --Michael Mol (talk) 20:59, 30 May 2020 (UTC)

# Angles (geometric), normalization and conversion

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
•   mil

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${\displaystyle \pi }$   of a turn   (or   0.5/${\displaystyle \pi }$   of a turn)

Or, to put it another way,   for a full circle:

•   there are   360   degrees
•   there are   6,400   mils
•   there are   2${\displaystyle \pi }$   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)
•   °       (another symbol)

Gradians   are sometimes known or shown as:

•   gon(s)
•   metric degree(s)
•   (Note that   centigrade   was used for 1/100th of a grade, see the note below.)

Mils   are sometimes known or shown as:

•   mil(s)
•   NATO mil(s)

Radians   are sometimes known or shown as:

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.000000,   or   -0º   should be shown as   .

•   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

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

## 11l

Translation of: Nim
V values = [Float(-2), -1, 0, 1, 2, 6.2831853, 16, 57.2957795, 359, 399, 6399, 1000000] F normd(x) {R fmod(x, 360)}F normg(x) {R fmod(x, 400)}F normm(x) {R fmod(x, 6400)}F normr(x) {R fmod(x, (2 * math:pi))} F d2g(x) {R normd(x) * 10 / 9}F d2m(x) {R normd(x) * 160 / 9}F d2r(x) {R normd(x) * math:pi / 180} F g2d(x) {R normg(x) * 9 / 10}F g2m(x) {R normg(x) * 16}F g2r(x) {R normg(x) * math:pi / 200} F m2d(x) {R normm(x) * 9 / 160}F m2g(x) {R normm(x) / 16}F m2r(x) {R normm(x) * math:pi / 3200} F r2d(x) {R normr(x) * 180 / math:pi}F r2g(x) {R normr(x) * 200 / math:pi}F r2m(x) {R normr(x) * 3200 / math:pi} print(‘       Degrees        Normalized         Gradians          Mils            Radians’)print(‘───────────────────────────────────────────────────────────────────────────────────’)L(val) values   print(‘#7.7  #7.7  #7.7  #7.7  #7.7’.format(val, normd(val), d2g(val), d2m(val), d2r(val))) print()print(‘      Gradians        Normalized         Degrees           Mils            Radians’)print(‘───────────────────────────────────────────────────────────────────────────────────’)L(val) values   print(‘#7.7  #7.7  #7.7  #7.7  #7.7’.format(val, normg(val), g2d(val), g2m(val), g2r(val))) print()print(‘        Mils          Normalized         Degrees         Gradians          Radians’)print(‘───────────────────────────────────────────────────────────────────────────────────’)L(val) values   print(‘#7.7  #7.7  #7.7  #7.7  #7.7’.format(val, normm(val), m2d(val), m2g(val), m2r(val))) print()print(‘       Radians        Normalized         Degrees         Gradians          Mils’)print(‘───────────────────────────────────────────────────────────────────────────────────’)L(val) values   print(‘#7.7  #7.7  #7.7  #7.7  #7.7’.format(val, normr(val), r2d(val), r2g(val), r2m(val)))
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

───────────────────────────────────────────────────────────────────────────────────
-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.5662015      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

───────────────────────────────────────────────────────────────────────────────────
-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

───────────────────────────────────────────────────────────────────────────────────
-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


## AutoHotkey

testAngles := [-2, -1, 0, 1, 2, 6.2831853, 16, 57.2957795, 359, 399, 6399, 1000000] result .= "Degrees    Degrees    Gradians    Mils    Radiansn"for i, a in testAngles    result .= a "t" Deg2Deg(a) "t" Deg2Grad(a) "t" Deg2Mil(a) "t" Deg2Rad(a) "n"result .= "nGradians    Degrees    Gradians    Mils    Radiansn"for i, a in testAngles    result .= a "t" Grad2Deg(a) "t" Grad2Grad(a) "t" Grad2Mil(a) "t" Grad2Rad(a) "n"result .= "nMills    Degrees    Gradians    Mils    Radiansn"for i, a in testAngles    result .= a "t" Mil2Deg(a) "t" Mil2Grad(a) "t" Mil2Mil(a) "t" Mil2Rad(a) "n"result .= "nRadians    Degrees    Gradians    Mils    Radiansn"for i, a in testAngles    result .= a "t" Rad2Deg(a) "t" Rad2Grad(a) "t" Rad2Mil(a) "t" Rad2Rad(a) "n" MsgBox, 262144, , % resultreturn;-------------------------------------------------------Deg2Deg(Deg){    return Mod(Deg, 360)}Deg2Grad(Deg){    return Deg2Deg(Deg) * 400 / 360}Deg2Mil(Deg){    return Deg2Deg(Deg) * 6400 / 360}Deg2Rad(Deg){    return Deg2Deg(Deg) * (π:=3.141592653589793) / 180};-------------------------------------------------------Grad2Grad(Grad){    return Mod(Grad, 400)}Grad2Deg(Grad){    return Grad2Grad(Grad) * 360 / 400}Grad2Mil(Grad){    return Grad2Grad(Grad) * 6400 / 400}Grad2Rad(Grad){    return Grad2Grad(Grad) * (π:=3.141592653589793) / 200};-------------------------------------------------------Mil2Mil(Mil){    return Mod(Mil, 6400)}Mil2Deg(Mil){    return Mil2Mil(Mil) * 360 / 6400}Mil2Grad(Mil){    return Mil2Mil(Mil) * 400 / 6400}Mil2Rad(Mil){    return Mil2Mil(Mil) * (π:=3.141592653589793) / 3200};-------------------------------------------------------Rad2Rad(Rad){    return Mod(Rad, 2*(π:=3.141592653589793))}Rad2Deg(Rad){    return Rad2Rad(Rad) * 180 / (π:=3.141592653589793)}Rad2Grad(Rad){    return Rad2Rad(Rad) * 200 / (π:=3.141592653589793)}Rad2Mil(Rad){    return Rad2Rad(Rad) * 3200 / (π:=3.141592653589793)};-------------------------------------------------------
Output:
Degrees		Degrees		Gradians	Mils		Radians
-2		-2		-2.222222	-35.555556	-0.034907
-1		-1		-1.111111	-17.777778	-0.017453
0		0		0.000000	0.000000	0.000000
1		1		1.111111	17.777778	0.017453
2		2		2.222222	35.555556	0.034907
6.2831853	6.283185	6.981317	111.701072	0.109662
16		16		17.777778	284.444444	0.279253
57.2957795	57.295780	63.661977	1018.591636	1.000000
359		359		398.888889	6382.222222	6.265732
399		39		43.333333	693.333333	0.680678
6399		279		310.000000	4960.000000	4.869469
1000000		280		311.111111	4977.777778	4.886922

-2		-1.800000	-2		-32.000000	-0.031416
-1		-0.900000	-1		-16.000000	-0.015708
0		0.000000	0		0.000000	0.000000
1		0.900000	1		16.000000	0.015708
2		1.800000	2		32.000000	0.031416
6.2831853	5.654867	6.283185	100.530965	0.098696
16		14.400000	16		256.000000	0.251327
57.2957795	51.566202	57.295780	916.732472	0.900000
359		323.100000	359		5744.000000	5.639159
399		359.100000	399		6384.000000	6.267477
6399		359.100000	399		6384.000000	6.267477
1000000		0.000000	0		0.000000	0.000000

-2		-0.112500	-0.125000	-2		-0.001963
-1		-0.056250	-0.062500	-1		-0.000982
0		0.000000	0.000000	0		0.000000
1		0.056250	0.062500	1		0.000982
2		0.112500	0.125000	2		0.001963
6.2831853	0.353429	0.392699	6.283185	0.006169
16		0.900000	1.000000	16		0.015708
57.2957795	3.222888	3.580986	57.295780	0.056250
359		20.193750	22.437500	359		0.352447
399		22.443750	24.937500	399		0.391717
6399		359.943750	399.937500	6399		6.282204
1000000		90.000000	100.000000	1600		1.570796

-2		-114.591559	-127.323954	-2037.183272	-2.000000
-1		-57.295780	-63.661977	-1018.591636	-1.000000
0		0.000000	0.000000	0.000000	0.000000
1		57.295780	63.661977	1018.591636	1.000000
2		114.591559	127.323954	2037.183272	2.000000
6.2831853	360.000000	400.000000	6399.999993	6.283185
16		196.732472	218.591636	3497.466173	3.433629
57.2957795	42.806349	47.562610	761.001765	0.747112
359		49.184845	54.649828	874.397248	0.858437
399		181.016026	201.128917	3218.062679	3.159326
6399		155.693104	172.992338	2767.877408	2.717357
1000000		339.513082	377.236758	6035.788130	5.925621

## 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) } 
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

#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;}

## C#

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;}
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++

Library: Boost
#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;}
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        │
└─────────────────┴───────────────────┘
...
┌───────────────────┐
┌─────────────────┼───────────────────┤
│       -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.

(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   [email protected]   [email protected]   [email protected]   [email protected]   [email protected]~%" "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))))
Output:
[CLISP]> (angles)
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

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

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

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

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

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

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

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

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

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

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

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

Library: System.Math
Translation of: Go
 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. ## 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.) USING: accessors combinators formatting inverse kernel mathmath.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 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. #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 nend 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 selectend 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, targdim 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 inext k  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 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))) }} 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. 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 extends Angle> B asType(Class<B> 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) }} This category class allows Angles to interoperate more easily with Numbers: 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) }} Test: 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 demonstrationassert 360.deg == 0.degassert 90.deg == 100.gradassert Math.PI.rad == 3200.mil 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 ## Haskell The solution of this seemingly trivial task could be elegantly done by type classes. Each angle unit is represented as a distinct type, preventing from implicit combination of different units. Moreover, adding new units doesn't imply writing new transformers or normalizers. Isomorphims between all angular types are defined via representation as turns, according to the fact that they all form the same topological space, isomorphic to open interval (-1, 1). {-# LANGUAGE RankNTypes #-}{-# LANGUAGE TypeApplications #-}{-# LANGUAGE GeneralizedNewtypeDeriving #-} import Text.Printf class (Num a, Fractional a, RealFrac a) => Angle a where fullTurn :: a -- value of the whole turn mkAngle :: Double -> a value :: a -> Double fromTurn :: Double -> a toTurn :: a -> Double normalize :: a -> a -- conversion of angles to rotations in linear case fromTurn t = angle t * fullTurn toTurn a = value$ a / fullTurn   -- normalizer for linear angular unit  normalize a = a modulo fullTurn    where      modulo x r | x == r = r                 | x < 0 = signum x * abs x modulo r                 | x >= 0 = x - fromInteger (floor (x / r)) * r  -- smart constructorangle :: Angle a => Double -> aangle = normalize . mkAngle -- Two transformers differ only in the order of type application.from :: forall a b. (Angle a, Angle b) => a -> bfrom = fromTurn . toTurn to :: forall b a. (Angle a, Angle b) => a -> bto = fromTurn . toTurn

Instances of different angular units.

-- radiansnewtype Rad = Rad Double  deriving (Eq, Ord, Num, Real, Fractional, RealFrac, Floating) instance Show Rad where  show (Rad 0) = printf "∠0"   show (Rad r) = printf "∠%.3f" r  instance Angle Rad where  fullTurn = Rad 2*pi  mkAngle = Rad  value (Rad r) = r -- degreesnewtype Deg = Deg Double  deriving (Eq, Ord, Num, Real, Fractional, RealFrac, Floating) instance Show Deg where  show (Deg 0) = printf "0°"  show (Deg d) =  printf "%.3g°" d instance Angle Deg where  fullTurn = Deg 360  mkAngle = Deg  value (Deg d) = d -- grads newtype Grad = Grad Double  deriving (Eq, Ord, Num, Real, Fractional, RealFrac, Floating) instance Show Grad where  show (Grad 0) = printf "0g"  show (Grad g) = printf "%.3gg" g instance Angle Grad where  fullTurn = Grad 400  mkAngle = Grad  value (Grad g) = g -- milsnewtype Mil = Mil Double  deriving (Eq, Ord, Num, Real, Fractional, RealFrac, Floating) instance Show Mil where  show (Mil 0) = printf "0m"  show (Mil m) =  printf "%.3gm" m instance Angle Mil where  fullTurn = Mil 6400  mkAngle = Mil  value (Mil m) = m  -- example of non-linear angular unit newtype Slope = Slope Double  deriving (Eq, Ord, Num, Real, Fractional, RealFrac, Floating) instance Show Slope where  show (Slope 0) = printf "0%"  show (Slope m) = printf "%.g" (m * 100) ++ "%" instance Angle Slope where  fullTurn = undefined  mkAngle = Slope  value (Slope t) = t  toTurn   = toTurn @Rad . angle . atan . value  fromTurn = angle . tan . value . fromTurn @Rad  normalize = id

Examples

λ> angle 45 :: Deg
45.000°

∠3.141

λ> angle 1000 :: Gon
200.000g

λ> normalize 450 :: Deg
90.000°

λ> normalize 450 :: Gon
50.000g

λ> (from :: Gon -> Rad) 100
∠1.571

λ> (from :: Rad -> Gon) $(pi/2) 100.000g λ> (from :: Deg -> Slope) 45 100% λ> (from :: Slope -> Mil) 0.5 472.267m λ> :set -XTypeApplications λ> from @Gon @Deg (angle 100) 90.000° λ> to @Gon (angle @Deg 45) 50.000g The task assignment shows different possible type annotations. main = do let xs = [-2, -1, 0, 1, 2, 6.2831853, 16, 57.2957795, 359, 399, 6399, 1000000] -- using to and angle with type application putStrLn "converting to radians" print$ to @Rad . angle @Rad <$> xs print$ to @Rad . angle @Deg <$> xs print$ to @Rad . angle @Grad <$> xs print$ to @Rad . angle @Mil <$> xs print$ to @Rad . angle @Slope <$> xs -- using from with type application putStrLn "\nconverting to degrees" print$ from @Rad @Deg . angle <$> xs print$ from @Deg @Deg . angle <$> xs print$ from @Grad @Deg . angle <$> xs print$ from @Mil @Deg . angle <$> xs print$ from @Slope @Deg . angle <$> xs -- using normalization for each unit putStrLn "\nconverting to grads" print$ to @Grad . normalize . Rad <$> xs print$ to @Grad . normalize . Deg <$> xs print$ to @Grad . normalize . Grad <$> xs print$ to @Grad . normalize . Mil <$> xs print$ to @Grad . normalize . Slope <$> xs -- using implicit type annotation putStrLn "\nconverting to mils" print$ (from :: Rad -> Mil) . angle <$> xs print$ (from :: Deg -> Mil) . angle <$> xs print$ (from :: Grad -> Mil) . angle <$> xs print$ (from :: Mil -> Mil) . angle <$> xs print$ (from :: Slope -> Mil) . angle <$> xs λ> main converting to radians [∠-2.000,∠-1.000,∠0,∠1.000,∠2.000,∠6.283,∠3.434,∠0.747,∠0.858,∠3.159,∠2.717,∠5.926] [∠-0.035,∠-0.017,∠0,∠0.017,∠0.035,∠0.110,∠0.279,∠1.000,∠6.266,∠0.681,∠4.869,∠4.887] [∠-0.031,∠-0.016,∠0,∠0.016,∠0.031,∠0.099,∠0.251,∠0.900,∠5.639,∠6.267,∠6.267,∠0] [∠-0.002,∠-0.001,∠0,∠0.001,∠0.002,∠0.006,∠0.016,∠0.056,∠0.352,∠0.392,∠6.282,∠1.571] [∠-1.107,∠-0.785,∠0,∠0.785,∠1.107,∠1.413,∠1.508,∠1.553,∠1.568,∠1.568,∠1.571,∠1.571] converting to degrees [-114.592°,-57.296°,0°,57.296°,114.592°,360.000°,196.732°,42.806°,49.185°,181.016°,155.693°,339.513°] [-2.000°,-1.000°,0°,1.000°,2.000°,6.283°,16.000°,57.296°,359.000°,39.000°,279.000°,280.000°] [-1.800°,-0.900°,0°,0.900°,1.800°,5.655°,14.400°,51.566°,323.100°,359.100°,359.100°,0°] [-0.112°,-5.625e-2°,0°,5.625e-2°,0.112°,0.353°,0.900°,3.223°,20.194°,22.444°,359.944°,90.000°] [-63.435°,-45.000°,0°,45.000°,63.435°,80.957°,86.424°,89.000°,89.840°,89.856°,89.991°,90.000°] converting to grads [-127.324g,-63.662g,0g,63.662g,127.324g,400.000g,218.592g,47.563g,54.650g,201.129g,172.992g,377.237g] [-2.222g,-1.111g,0g,1.111g,2.222g,6.981g,17.778g,63.662g,398.889g,43.333g,310.000g,311.111g] [-2.000g,-1.000g,0g,1.000g,2.000g,6.283g,16.000g,57.296g,359.000g,399.000g,399.000g,0g] [-0.125g,-6.250e-2g,0g,6.250e-2g,0.125g,0.393g,1.000g,3.581g,22.438g,24.938g,399.938g,100.000g] [-70.483g,-50.000g,0g,50.000g,70.483g,89.952g,96.026g,98.889g,99.823g,99.840g,99.990g,100.000g] converting to mils [-2037.183m,-1018.592m,0m,1018.592m,2037.183m,6400.000m,3497.466m,761.002m,874.397m,3218.063m,2767.877m,6035.788m] [-35.556m,-17.778m,0m,17.778m,35.556m,111.701m,284.444m,1018.592m,6382.222m,693.333m,4960.000m,4977.778m] [-32.000m,-16.000m,0m,16.000m,32.000m,100.531m,256.000m,916.732m,5744.000m,6384.000m,6384.000m,0m] [-2.000m,-1.000m,0m,1.000m,2.000m,6.283m,16.000m,57.296m,359.000m,399.000m,6399.000m,1600.000m] [-1127.732m,-800.000m,0m,800.000m,1127.732m,1439.234m,1536.421m,1582.224m,1597.163m,1597.447m,1599.841m,1599.999m] ## 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:  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'  we can compose conversion sentences like  as_degree 100 Gradian90  Presuming the following additional definitions:  NAMES =: > turndegreegradianmilradian ALL =: as_turnas_degreeas_gradianas_milas_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|+-------+---------------------------------------------------------------------------------------------------+  ## 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; } } 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  ## JavaScript  /*****************************************************************\| Expects an angle, an origin unit and a unit to convert to, || where in/out units are: || --------------------------------------------------------------- || 'D'/'d' ..... degrees 'M'/'d' ..... mils | || 'G'/'g' ..... gradians 'R'/'r' ..... radians || --------------------------------------------------------------- || example: convert 150 degrees to radians: || angleConv(150, 'd', 'r') |\*****************************************************************/function angleConv(deg, inp, out) { inp = inp.toLowerCase(); out = out.toLowerCase(); const D = 360, G = 400, M = 6400, R = 2 * Math.PI; // normalazation let minus = (deg < 0); // boolean deg = Math.abs(deg); switch (inp) { case 'd': deg %= D; break; case 'g': deg %= G; break; case 'm': deg %= M; break; case 'r': deg %= R; } // we use an internal conversion to Turns (full circle) here let t; switch (inp) { case 'd': t = deg / D; break; case 'g': t = deg / G; break; case 'm': t = deg / M; break; case 'r': t = deg / R; } // converting switch (out) { case 'd': t *= D; break; case 'g': t *= G; break; case 'm': t *= M; break; case 'r': t *= R; } if (minus) return 0 - t; return t;} // mass testinglet nums = [-2, -1, 0, 1, 2, 6.2831853, 16, 57.2957795, 359, 399, 6399, 1e6], units = 'dgmr'.split(''), x, y, z;for (x = 0; x < nums.length; x++) { for (y = 0; y < units.length; y++) { document.write( <p> <b>${nums[x]}<sub>${units[y]}</sub></b><br> ); for (z = 0; z < units.length; z++) document.write( =${angleConv(nums[x], units[y], units[z])}<sub>${units[z]}</sub> ); }}  Output (without bolds and subs): Output:  -2d = -2d = -2.2222222222222223g = -35.55555555555556m = -0.03490658503988659r -2g = -1.8d = -2g = -32m = -0.031415926535897934r -2m = -0.1125d = -0.125g = -2m = -0.001963495408493621r -2r = -114.59155902616465d = -127.32395447351628g = -2037.1832715762605m = -2r -1d = -1d = -1.1111111111111112g = -17.77777777777778m = -0.017453292519943295r -1g = -0.9d = -1g = -16m = -0.015707963267948967r -1m = -0.05625d = -0.0625g = -1m = -0.0009817477042468104r -1r = -57.29577951308232d = -63.66197723675814g = -1018.5916357881302m = -1r 0d = 0d = 0g = 0m = 0r 0g = 0d = 0g = 0m = 0r 0m = 0d = 0g = 0m = 0r 0r = 0d = 0g = 0m = 0r 1d = 1d = 1.1111111111111112g = 17.77777777777778m = 0.017453292519943295r 1g = 0.9d = 1g = 16m = 0.015707963267948967r 1m = 0.05625d = 0.0625g = 1m = 0.0009817477042468104r 1r = 57.29577951308232d = 63.66197723675814g = 1018.5916357881302m = 1r 2d = 2d = 2.2222222222222223g = 35.55555555555556m = 0.03490658503988659r 2g = 1.8d = 2g = 32m = 0.031415926535897934r 2m = 0.1125d = 0.125g = 2m = 0.001963495408493621r 2r = 114.59155902616465d = 127.32395447351628g = 2037.1832715762605m = 2r 6.2831853d = 6.2831853d = 6.981317000000001g = 111.70107200000001m = 0.10966227099790768r 6.2831853g = 5.654866770000001d = 6.2831853g = 100.5309648m = 0.09869604389811691r 6.2831853m = 0.35342917312500005d = 0.39269908125g = 6.2831853m = 0.006168502743632307r 6.2831853r = 359.99999958864004d = 399.9999995429334g = 6399.999992686934m = 6.2831853r 16d = 16d = 17.77777777777778g = 284.44444444444446m = 0.2792526803190927r 16g = 14.4d = 16g = 256m = 0.25132741228718347r 16m = 0.9d = 1g = 16m = 0.015707963267948967r 16r = 196.73247220931714d = 218.59163578813016g = 3497.4661726100826m = 3.433629385640827r 57.2957795d = 57.2957795d = 63.66197722222222g = 1018.5916355555555m = 0.9999999997716704r 57.2957795g = 51.56620155d = 57.2957795g = 916.732472m = 0.8999999997945033r 57.2957795m = 3.222887596875d = 3.58098621875g = 57.2957795m = 0.056249999987156456r 57.2957795r = 42.80634926218226d = 47.56261029131362g = 761.0017646610179m = 0.7471117353837258r 359d = 359d = 398.8888888888889g = 6382.222222222223m = 6.265732014659643r 359g = 323.09999999999997d = 359g = 5744m = 5.639158813193679r 359m = 20.193749999999998d = 22.4375g = 359m = 0.3524474258246049r 359r = 49.184845196553994d = 54.649827996171105g = 874.3972479387377m = 0.8584374907635848r 399d = 39d = 43.333333333333336g = 693.3333333333334m = 0.6806784082777886r 399g = 359.1d = 399g = 6384m = 6.267477343911637r 399m = 22.44375d = 24.9375g = 399m = 0.39171733399447733r 399r = 181.0160257198469d = 201.12891746649657g = 3218.062679463945m = 3.1593256476860674r 6399d = 279d = 310g = 4960m = 4.869468613064179r 6399g = 359.1d = 399g = 6384m = 6.267477343911637r 6399m = 359.94375d = 399.9375g = 6399m = 6.28220355947534r 6399r = 155.69310421378557d = 172.9923380153173g = 2767.877408245077m = 2.717357291181216r 1000000d = 280d = 311.11111111111114g = 4977.777777777778m = 4.886921905584122r 1000000g = 0d = 0g = 0m = 0r 1000000m = 90d = 100g = 1600m = 1.5707963267948966r 1000000r = 339.51308232311027d = 377.2367581367892g = 6035.788130188627m = 5.925621140132833r  ## jq Adapted from #Wren Works with: jq Works with gojq, the Go implementation of jq Preliminaries ### Formatting # Right-justify but do not truncatedef rjustify(n): tostring | length as$length | if n <= $length then . else " " * (n-$length) + . end; # Attempt to align decimals so integer part is in a field of width ndef align($n): tostring | index(".") as$ix  | if $ix then if$n < $ix then . elif$ix then (.[0:$ix]|rjustify($n)) +.[$ix:] else rjustify($n)         end    else . + ".0" | align($n) end ; # number of decimal places ($n>=0)def fround($n): pow(10;$n) as $p | (. *$p | round ) / $p | tostring | index(".") as$ix  | ("0" * $n) as$zeros  | if $ix then . +$zeros | .[0 : $ix +$n + 1]    else . + "." + $zeros end; def hide_trailing_zeros: tostring | (capture("(?<x>[^.]*[.].)(?<y>00*$)") // null) as $capture | if$capture    then $capture | (.x + (.y|gsub("0"; " "))) else . end; def lpad($len): tostring | ($len - length) as$l | (" " * $l)[:$l] + .;

# Normalization as per the task requirementsdef mod($y): (if . < 0 then -$y else 0 end) as $adjust |$adjust + . - ($y * ((. /$y)|floor)); def pi: (1|atan) * 4; def d2d: mod(360);def g2g: mod(400);def m2m: mod(6400);def r2r: mod(2*pi);def d2g: d2d * 400 / 360;def d2m: d2d * 6400 / 360;def d2r: d2d * pi / 180;def g2d: g2g * 360 / 400;def g2m: g2g * 6400 / 400;def g2r: g2g * pi / 200;def m2d: m2m * 360 / 6400;def m2g: m2m * 400 / 6400;def m2r: m2m * pi / 3200;def r2d: r2r * 180 / pi;def r2g: r2r * 200 / pi;def r2m: r2r * 3200 / pi; def f1(a;b;c;d;e): "\(a|lpad(15)) \(b|lpad(15)) \(c|lpad(15)) \(d|lpad(15)) \(e|lpad(15))"; def f2(a;b;c;d;e):  def al: fround(7) | align(10)| hide_trailing_zeros;  "\(a|al) \(b|al) \(c|al) \(d|al) \(e|al)"; def angles: [-2, -1, 0, 1, 2, 6.2831853, 16, 57.2957795, 359, 399, 6399, 1000000]; def task1:  f1( "degrees";  "normalized degs"; "gradians"; "mils"; "radians"),  (angles[]   | f2(.; d2d; d2g; d2m; d2r)) ; def task2:  f1("gradians"; "normalized grds"; "degrees"; "mils"; "radians"),  (angles[]   | f2(.; g2g; g2d; g2m; g2r)); def task3:  f1("mils"; "normalized mils"; "degrees"; "gradians"; "radians"),  (angles[]   | f2(.; m2m; m2d; m2g; m2r)); def task4:  f1( "radians"; "normalized rads"; "degrees"; "gradians"; "mils"),  ( angles[]   | f2(.; r2r; r2d; r2g; r2m) ); task1, "",task2, "",task3, "",task4
Output:
As for [[#Wren]]


## Julia

using Formatting d2d(d) = d % 360g2g(g) = g % 400m2m(m) = m % 6400r2r(r) = r % 2πd2g(d) = d2d(d) * 10 / 9d2m(d) = d2d(d) * 160 / 9d2r(d) = d2d(d) * π / 180g2d(g) = g2g(g) * 9 / 10g2m(g) = g2g(g) * 16g2r(g) = g2g(g) * π / 200m2d(m) = m2m(m) * 9 / 160m2g(m) = m2m(m) / 16m2r(m) = m2m(m) * π / 3200r2d(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()    endend testconversions([-2, -1, 0, 1, 2, 6.2831853, 16, 57.2957795, 359, 399, 6399, 1000000])
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

Translation of: Java
import java.text.DecimalFormat as DF const val DEGREE = 360.0const val GRADIAN = 400.0const val MIL = 6400.0const val RADIAN = 2 * Math.PI fun d2d(a: Double) = a % DEGREEfun 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 % GRADIANfun 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 % MILfun 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)))        }}
Output:

See Java output

## 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))  endend

Optionally:

-- 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") endfunction d2g(n) return convert(n,"degrees","gradians") endfunction d2m(n) return convert(n,"degrees","mils") endfunction d2r(n) return convert(n,"degrees","radians") endfunction g2d(n) return convert(n,"gradians","degrees") endfunction g2g(n) return convert(n,"gradians","gradians") endfunction g2m(n) return convert(n,"gradians","mils") endfunction g2r(n) return convert(n,"gradians","radians") endfunction m2d(n) return convert(n,"mils","degrees") endfunction m2g(n) return convert(n,"mils","gradians") endfunction m2m(n) return convert(n,"mils","mils")  endfunction m2r(n) return convert(n,"mils","radians") endfunction r2d(n) return convert(n,"radians","degrees") endfunction r2g(n) return convert(n,"radians","gradians") endfunction r2m(n) return convert(n,"radians","mils") endfunction r2r(n) return convert(n,"radians","radians") end
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

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/360Degree2Mil[d_] := d 6400/360Degree2Radian[d_] := d Pi/180Gradian2Degree[d_] := d 360/400Gradian2Mil[d_] := d 6400/400Gradian2Radian[d_] := d 2 Pi/400Mil2Degree[d_] := d 360/6400Mil2Gradian[d_] := d 400/6400Mil2Radian[d_] := d 2 Pi/6400Radian2Degree[d_] := d 180/PiRadian2Gradian[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}}]
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

import mathimport 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 360func g2g(x: float): float {.inline.} = x mod 400func m2m(x: float): float {.inline.} = x mod 6400func r2r(x: float): float {.inline.} = x mod (2 * Pi) func d2g(x: float): float {.inline.} = d2d(x) * 10 / 9func d2m(x: float): float {.inline.} = d2d(x) * 160 / 9func d2r(x: float): float {.inline.} = d2d(x) * Pi / 180 func g2d(x: float): float {.inline.} = g2g(x) * 9 / 10func g2m(x: float): float {.inline.} = g2g(x) * 16func g2r(x: float): float {.inline.} = g2g(x) * Pi / 200 func m2d(x: float): float {.inline.} = m2m(x) * 9 / 160func m2g(x: float): float {.inline.} = m2m(x) / 16func m2r(x: float): float {.inline.} = m2m(x) * Pi / 3200 func r2d(x: float): float {.inline.} = r2r(x) * 180 / Pifunc r2g(x: float): float {.inline.} = r2r(x) * 200 / Pifunc 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}"
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

———————————————————————————————————————————————————————————————————————————————————
-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

———————————————————————————————————————————————————————————————————————————————————
-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

———————————————————————————————————————————————————————————————————————————————————
-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

Translation of: Raku
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; }} 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 PI = 3.141592653589793TWO_PI = 6.283185307179586 def normalize2deg(a): while a < 0: a += 360 while a >= 360: a -= 360 return adef normalize2grad(a): while a < 0: a += 400 while a >= 400: a -= 400 return adef normalize2mil(a): while a < 0: a += 6400 while a >= 6400: a -= 6400 return adef 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.0def deg2mil(a): return a * 160.0 / 9.0def deg2rad(a): return a * PI / 180.0 def grad2deg(a): return a * 9.0 / 10.0def grad2mil(a): return a * 16.0def grad2rad(a): return a * PI / 200.0 def mil2deg(a): return a * 9.0 / 160.0def mil2grad(a): return a / 16.0def mil2rad(a): return a * PI / 3200.0 def rad2deg(a): return a * 180.0 / PIdef rad2grad(a): return a * 200.0 / PIdef rad2mil(a): return a * 3200.0 / PI ### Python: using tkinter  ''' 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 messageboximport 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.  ## Racket Translation of: Common Lisp #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"))) 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)  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.<code>}2{$b.<code>}" => 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.<code>}2{.<code>}" }; my @results = %cvt{@sub_keys}».($angle);         say join ' ', $angle .fmt('%10g'),$from.<name>.fmt('%-8s'),                      @results    .fmt('%11g');    }}
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.)

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); }}  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 /*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 pid2g: 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.*/ 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. 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 #Demonames = Angles::BASES.keysputs " " + "%12s "*names.size % namestest = [-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 putsend  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 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<U> {        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>();}
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

-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

-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

-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

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()} 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 Translation of: Go Library: Wren-fmt 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" + f1Fmt.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))}
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

-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

-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

-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

Translation of: Raku
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	    })	  });
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(" ")));   }   }
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