Task: Angles (geometric), normalization and conversion



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



Java: import java.text.DecimalFormat;



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