# Critique for my first (potential) Rosetta Code Task: Angles Geometric Normalization and Conversion

Hi;

Do I need to have a GitHub account (or something similar) or can I post code here for constructive criticism? I guess I have a GitHub account (for use with creatingbug reports for MacPorts) but I have never used it to create code projects.

Since my code is only 223 lines, I’ll post it here unless there are complaints about it being too large for posting.

I have translated from C and Lua an unimplemented Rosetta Code Task.

Three questions…

I’m using literal whitespace for column alignment for the table; this looks like it would be hard to maintain. Is there are better way to format for alignment?

I did not specify a particular float type or precision; I think that I should try to aim for double precision if I am to follow the C example.

The Lua example was much more compact as it leveraged the unit name as data (?); is there a way to make the table like a template and fill it in as needed? This would make the code much easier to maintain.

I wrote two versions, one with descriptive function names and the second one using very minimal naming as suggested in the task description.

The C solution normalized negative data towards non-negative values; I inconsistently followed the task specification more closely and preserved the sign of the specific test data for degree units only. Do people use negative rads, grads and mils? I guess so if one is being relative insread of absolute…

– Angles (geometric), normalization and conversion
Angles (geometric), normalization and conversion - Rosetta Code
– translation from C (conversion functions) and (loosely) Lua (output table formatting)
– July 2024, R. B. E.

– To Do:
– Specific float format/precision rather than generic?

procedure Angles_Geometric_Normalization_and_Conversion is
Two_Pi : constant := 2.0 * Ada.Numerics.Pi;

function Normalize_to_Deg (a : Float) return Float is
tmp : Float := a;
begin
– while (tmp < 0.0) loop
while (tmp < -360.0) loop
tmp := tmp + 360.0;
end loop;
while (tmp >= 360.0) loop
tmp := tmp - 360.0;
end loop;
return tmp;
end Normalize_to_Deg;

function Normalize_to_Grad (a : Float) return Float is
tmp : Float := a;
begin
while (tmp < 0.0) loop
tmp := tmp + 400.0;
end loop;
while (tmp >= 400.0) loop
tmp := tmp - 400.0;
end loop;
return tmp;

function Normalize_to_Mil (a : Float) return Float is
tmp : Float := a;
begin
while (tmp < 0.0) loop
tmp := tmp + 6400.0;
end loop;
while (tmp >= 6400.0) loop
tmp := tmp - 6400.0;
end loop;
return tmp;
end Normalize_to_Mil;

function Normalize_to_Rad (a : Float) return Float is
tmp : Float := a;
begin
while (tmp < 0.0) loop
tmp := tmp + Two_Pi;
end loop;
while (tmp >= Two_Pi) loop
tmp := tmp - Two_Pi;
end loop;
return tmp;

function Deg_to_Grad (a : Float) return Float is
tmp : Float := a;
begin
tmp := a * (10.0 / 9.0);
return tmp;

function Deg_to_Mil (a : Float) return Float is
tmp : Float := a;
begin
tmp := a * (160.0 / 9.0);
return tmp;
end Deg_to_Mil;

function Deg_to_Rad (a : Float) return Float is
tmp : Float := a;
begin
tmp := a * (Pi / 180.0);
return tmp;

function Grad_to_Deg (a : Float) return Float is
tmp : Float := a;
begin
tmp := a * (9.0 / 10.0);
return tmp;

function Grad_to_Mil (a : Float) return Float is
tmp : Float := a;
begin
tmp := a * 16.0;
return tmp;

tmp : Float := a;
begin
tmp := a * (Pi / 200.0);
return tmp;

function Mil_to_Deg (a : Float) return Float is
tmp : Float := a;
begin
tmp := a * (9.0 / 160.0);
return tmp;
end Mil_to_Deg;

function Mil_to_Grad (a : Float) return Float is
tmp : Float := a;
begin
tmp := a / 16.0;
return tmp;

function Mil_to_Rad (a : Float) return Float is
tmp : Float := a;
begin
tmp := a * (Pi / 3200.0);
return tmp;

function Rad_to_Deg (a : Float) return Float is
tmp : Float := a;
begin
tmp := a * (180.0 / Pi);
return tmp;

tmp : Float := a;
begin
tmp := a * (200.0 / Pi);
return tmp;

function Rad_to_Mil (a : Float) return Float is
tmp : Float := a;
begin
tmp := a * (3200.0 / Pi);
return tmp;

type Index is range 1 … 12;
type Test_Values_Array is array (Index) of Float;
Test_Values : Test_Values_Array :=
(Float (-2), Float (-1), Float (0), Float (1), Float (2),
6.2831853, Float (16), 57.2957795, Float (359),
Float (399), Float (6399), Float (1000000));

begin
Put_Line (" TEST VALUE Normalized Converted Converted Converted");
for I in Index loop
Put (Test_Values (I), Exp => 0, Aft => 8, Fore => 8);
Put (" “);
Put (Normalize_to_Deg (Test_Values (I)), Exp => 0, Aft => 8, Fore => 4);
Put (” “);
Put (Deg_to_Grad (Normalize_to_Deg (Test_Values (I))), Exp => 0, Aft => 8, Fore => 4);
Put (” “);
Put (Deg_to_Mil (Normalize_to_Deg (Test_Values (I))), Exp => 0, Aft => 8, Fore => 4);
Put (” ");
Put (Deg_to_Rad (Normalize_to_Deg (Test_Values (I))), Exp => 0, Aft => 8, Fore => 2);
New_Line;
end loop;

New_Line;
Put_Line (" TEST VALUE Normalized Converted Converted Converted");
for I in Index loop
Put (Test_Values (I), Exp => 0, Aft => 8, Fore => 8);
Put (" “);
Put (Normalize_to_Grad (Test_Values (I)), Exp => 0, Aft => 8, Fore => 4);
Put (” “);
Put (Grad_to_Mil (Normalize_to_Grad (Test_Values (I))), Exp => 0, Aft => 8, Fore => 4);
Put (” “);
Put (” ");
Put (Grad_to_Deg (Normalize_to_Grad (Test_Values (I))), Exp => 0, Aft => 8, Fore => 4);
New_Line;
end loop;

New_Line;
Put_Line (" TEST VALUE Normalized Converted Converted Converted");
for I in Index loop
Put (Test_Values (I), Exp => 0, Aft => 8, Fore => 8);
Put (" “);
Put (Normalize_to_Mil (Test_Values (I)), Exp => 0, Aft => 8, Fore => 4);
Put (” “);
Put (Mil_to_Rad (Normalize_to_Mil (Test_Values (I))), Exp => 0, Aft => 8, Fore => 2);
Put (” “);
Put (Mil_to_Deg (Normalize_to_Mil (Test_Values (I))), Exp => 0, Aft => 8, Fore => 4);
Put (” ");
Put (Mil_to_Grad (Normalize_to_Mil (Test_Values (I))), Exp => 0, Aft => 8, Fore => 4);
New_Line;
end loop;

New_Line;
Put_Line (" TEST VALUE Normalized Converted Converted Converted");
for I in Index loop
Put (Test_Values (I), Exp => 0, Aft => 8, Fore => 8);
Put (" “);
Put (Normalize_to_Rad (Test_Values (I)), Exp => 0, Aft => 8, Fore => 4);
Put (” “);
Put (Rad_to_Deg (Normalize_to_Rad (Test_Values (I))), Exp => 0, Aft => 8, Fore => 4);
Put (” “);
Put (” ");
Put (Rad_to_Mil (Normalize_to_Rad (Test_Values (I))), Exp => 0, Aft => 8, Fore => 4);
New_Line;
end loop;

## end Angles_Geometric_Normalization_and_Conversion;

Thanks,
Retired_Build_Engineer

Your code is hard to read as it is not correctly formatted.
To format it correctly please enclose it with 3 backticks followed by ada at the beginning, like this…

`````````ada
``````

…and 3 backticks at the end of your code.

``````-- Rosetta Code Task written in Ada
-- Angles (geometric), normalization and conversion
-- https://rosettacode.org/wiki/Angles_(geometric),_normalization_and_conversion
-- translation from C (conversion functions) and (loosely) Lua (output table formatting)
-- July 2024, R. B. E.

-- To Do:
-- Specific float format/precision rather than generic?

procedure Angles_Geometric_Normalization_and_Conversion is
Two_Pi : constant := 2.0 * Ada.Numerics.Pi;

function Normalize_to_Deg (a : Float) return Float is
tmp : Float := a;
begin
--    while (tmp < 0.0) loop
while (tmp < -360.0) loop
tmp := tmp + 360.0;
end loop;
while (tmp >= 360.0) loop
tmp := tmp - 360.0;
end loop;
return tmp;
end Normalize_to_Deg;

function Normalize_to_Grad (a : Float) return Float is
tmp : Float := a;
begin
while (tmp < 0.0) loop
tmp := tmp + 400.0;
end loop;
while (tmp >= 400.0) loop
tmp := tmp - 400.0;
end loop;
return tmp;

function Normalize_to_Mil (a : Float) return Float is
tmp : Float := a;
begin
while (tmp < 0.0) loop
tmp := tmp + 6400.0;
end loop;
while (tmp >= 6400.0) loop
tmp := tmp - 6400.0;
end loop;
return tmp;
end Normalize_to_Mil;

function Normalize_to_Rad (a : Float) return Float is
tmp : Float := a;
begin
while (tmp < 0.0) loop
tmp := tmp + Two_Pi;
end loop;
while (tmp >= Two_Pi) loop
tmp := tmp - Two_Pi;
end loop;
return tmp;

function Deg_to_Grad (a : Float) return Float is
tmp : Float := a;
begin
tmp := a * (10.0 / 9.0);
return tmp;

function Deg_to_Mil (a : Float) return Float is
tmp : Float := a;
begin
tmp := a * (160.0 / 9.0);
return tmp;
end Deg_to_Mil;

function Deg_to_Rad (a : Float) return Float is
tmp : Float := a;
begin
tmp := a * (Pi / 180.0);
return tmp;

function Grad_to_Deg (a : Float) return Float is
tmp : Float := a;
begin
tmp := a * (9.0 / 10.0);
return tmp;

function Grad_to_Mil (a : Float) return Float is
tmp : Float := a;
begin
tmp := a * 16.0;
return tmp;

tmp : Float := a;
begin
tmp := a * (Pi / 200.0);
return tmp;

function Mil_to_Deg (a : Float) return Float is
tmp : Float := a;
begin
tmp := a * (9.0 / 160.0);
return tmp;
end Mil_to_Deg;

function Mil_to_Grad (a : Float) return Float is
tmp : Float := a;
begin
tmp := a / 16.0;
return tmp;

function Mil_to_Rad (a : Float) return Float is
tmp : Float := a;
begin
tmp := a * (Pi / 3200.0);
return tmp;

function Rad_to_Deg (a : Float) return Float is
tmp : Float := a;
begin
tmp := a * (180.0 / Pi);
return tmp;

tmp : Float := a;
begin
tmp := a * (200.0 / Pi);
return tmp;

function Rad_to_Mil (a : Float) return Float is
tmp : Float := a;
begin
tmp := a * (3200.0 / Pi);
return tmp;

type Index is range 1 .. 12;
type Test_Values_Array is array (Index) of Float;
Test_Values : Test_Values_Array :=
(Float (-2), Float (-1), Float (0), Float (1), Float (2),
6.2831853, Float (16), 57.2957795, Float (359),
Float (399), Float (6399), Float (1000000));

begin
Put_Line ("      TEST VALUE      Normalized       Converted       Converted      Converted");
for I in Index loop
Put (Test_Values (I), Exp => 0, Aft => 8, Fore => 8);
Put ("   ");
Put (Normalize_to_Deg (Test_Values (I)), Exp => 0, Aft => 8, Fore => 4);
Put ("   ");
Put (Deg_to_Grad (Normalize_to_Deg (Test_Values (I))), Exp => 0, Aft => 8, Fore => 4);
Put ("   ");
Put (Deg_to_Mil (Normalize_to_Deg (Test_Values (I))), Exp => 0, Aft => 8, Fore => 4);
Put ("   ");
Put (Deg_to_Rad (Normalize_to_Deg (Test_Values (I))), Exp => 0, Aft => 8, Fore => 2);
New_Line;
end loop;

New_Line;
Put_Line ("      TEST VALUE      Normalized       Converted     Converted      Converted");
for I in Index loop
Put (Test_Values (I), Exp => 0, Aft => 8, Fore => 8);
Put ("   ");
Put (Normalize_to_Grad (Test_Values (I)), Exp => 0, Aft => 8, Fore => 4);
Put ("   ");
Put (Grad_to_Mil (Normalize_to_Grad (Test_Values (I))), Exp => 0, Aft => 8, Fore => 4);
Put ("   ");
Put ("   ");
Put (Grad_to_Deg (Normalize_to_Grad (Test_Values (I))), Exp => 0, Aft => 8, Fore => 4);
New_Line;
end loop;

New_Line;
Put_Line ("      TEST VALUE      Normalized       Converted     Converted      Converted");
for I in Index loop
Put (Test_Values (I), Exp => 0, Aft => 8, Fore => 8);
Put ("   ");
Put (Normalize_to_Mil (Test_Values (I)), Exp => 0, Aft => 8, Fore => 4);
Put ("   ");
Put (Mil_to_Rad (Normalize_to_Mil (Test_Values (I))), Exp => 0, Aft => 8, Fore => 2);
Put ("   ");
Put (Mil_to_Deg (Normalize_to_Mil (Test_Values (I))), Exp => 0, Aft => 8, Fore => 4);
Put ("   ");
Put (Mil_to_Grad (Normalize_to_Mil (Test_Values (I))), Exp => 0, Aft => 8, Fore => 4);
New_Line;
end loop;

New_Line;
Put_Line ("      TEST VALUE       Normalized        Converted     Converted      Converted");
for I in Index loop
Put (Test_Values (I), Exp => 0, Aft => 8, Fore => 8);
Put ("   ");
Put (Normalize_to_Rad (Test_Values (I)), Exp => 0, Aft => 8, Fore => 4);
Put ("   ");
Put (Rad_to_Deg (Normalize_to_Rad (Test_Values (I))), Exp => 0, Aft => 8, Fore => 4);
Put ("   ");
Put ("   ");
Put (Rad_to_Mil (Normalize_to_Rad (Test_Values (I))), Exp => 0, Aft => 8, Fore => 4);
New_Line;
end loop;

end Angles_Geometric_Normalization_and_Conversion;

``````
1 Like

I tried making this code “data driven” which may or may not be idiomatic Ada (I too am in the process of learning Ada best practices).
NOTE I followed the C code for the Normalize_To_Deg first while condition check on 0.0 rather than -360.0 used by you since that made the code simpler.

``````with Ada.Text_IO; use Ada.Text_IO;

procedure Angles_Geometric_Normalization_and_Conversion is
Two_Pi : constant := 2.0 * Ada.Numerics.Pi;

type Normalization_Types is (Normalize_To_Deg, Normalize_To_Grad, Normalize_To_Mil,

Normalization_Magnitudes : array (Normalization_Types) of Float :=
(Normalize_To_Deg => 360.0,
Normalize_To_Mil => 6400.0,

function Normalize (Normalization : Normalization_Types; A : Float)
return Float is
Magnitude : Float := Normalization_Magnitudes (Normalization);
Tmp : Float := A;
begin
while (tmp < 0.0) loop
Tmp := Tmp + Magnitude;
end loop;
while (Tmp >= Magnitude) loop
Tmp := Tmp - Magnitude;
end loop;
return Tmp;
end Normalize;

Conversions : array (Conversion_Types) of Float :=
Deg_To_Mil => 160.0 / 9.0,
Mil_To_Deg => 9.0 / 160.0,

function Convert (Conversion : Conversion_Types; A : Float)
return Float is
(a * Conversions (Conversion));

type Index is range 1 .. 12;
type Test_Values_Array is array (Index) of Float;
Test_Values : Test_Values_Array :=
(Float (-2), Float (-1), Float (0), Float (1), Float (2),
6.2831853, Float (16), 57.2957795, Float (359),
Float (399), Float (6399), Float (1000000));

begin
Put_Line ("      TEST VALUE      Normalized       Converted       Converted      Converted");
for I in Index loop
Put (Test_Values (I), Exp => 0, Aft => 8, Fore => 8);
Put ("   ");
Put (Normalize (Normalize_To_Deg, Test_Values (I)), Exp => 0, Aft => 8, Fore => 4);
Put ("   ");
Put (Convert (Deg_To_Grad, Normalize (Normalize_To_Deg, Test_Values (I))), Exp => 0, Aft => 8, Fore => 4);
Put ("   ");
Put (Convert (Deg_To_Mil, Normalize (Normalize_To_Deg, Test_Values (I))), Exp => 0, Aft => 8, Fore => 4);
Put ("   ");
Put (Convert (Deg_To_Rad, Normalize (Normalize_To_Deg, Test_Values (I))), Exp => 0, Aft => 8, Fore => 2);
New_Line;
end loop;

New_Line;
Put_Line ("      TEST VALUE      Normalized       Converted     Converted      Converted");
for I in Index loop
Put (Test_Values (I), Exp => 0, Aft => 8, Fore => 8);
Put ("   ");
Put (Normalize (Normalize_To_Grad, Test_Values (I)), Exp => 0, Aft => 8, Fore => 4);
Put ("   ");
Put (Convert (Grad_To_Mil, Normalize (Normalize_To_Grad, Test_Values (I))), Exp => 0, Aft => 8, Fore => 4);
Put ("   ");
Put ("   ");
Put (Convert (Grad_To_Deg, Normalize (Normalize_To_Grad, Test_Values (I))), Exp => 0, Aft => 8, Fore => 4);
New_Line;
end loop;

New_Line;
Put_Line ("      TEST VALUE      Normalized       Converted     Converted      Converted");
for I in Index loop
Put (Test_Values (I), Exp => 0, Aft => 8, Fore => 8);
Put ("   ");
Put (Normalize (Normalize_To_Mil, Test_Values (I)), Exp => 0, Aft => 8, Fore => 4);
Put ("   ");
Put (Convert (Mil_To_Rad, Normalize (Normalize_To_Mil, Test_Values (I))), Exp => 0, Aft => 8, Fore => 2);
Put ("   ");
Put (Convert (Mil_To_Deg, Normalize (Normalize_To_Mil, Test_Values (I))), Exp => 0, Aft => 8, Fore => 4);
Put ("   ");
Put (Convert (Mil_To_Grad, Normalize (Normalize_To_Mil, Test_Values (I))), Exp => 0, Aft => 8, Fore => 4);
New_Line;
end loop;

New_Line;
Put_Line ("      TEST VALUE       Normalized        Converted     Converted      Converted");
for I in Index loop
Put (Test_Values (I), Exp => 0, Aft => 8, Fore => 8);
Put ("   ");
Put (Normalize (Normalize_To_Rad, Test_Values (I)), Exp => 0, Aft => 8, Fore => 4);
Put ("   ");
Put (Convert (Rad_To_Deg, Normalize (Normalize_To_Rad, Test_Values (I))), Exp => 0, Aft => 8, Fore => 4);
Put ("   ");
Put ("   ");
Put (Convert (Rad_To_Mil, Normalize (Normalize_To_Rad, Test_Values (I))), Exp => 0, Aft => 8, Fore => 4);
New_Line;
end loop;

end Angles_Geometric_Normalization_and_Conversion;
``````

Hi Anuj;

Thank you for your response. I will be examining this to learn all I can about your alternative approach. This does look like it is easier to read (and therefore, maintain) than my version. If I submit your version (or even parts of what you wrote) I’ll mention that you were a contributor.

Retired_Build_Engineer

Hi All;

I have posted my original version (with a small update regarding the literal whitespace padding for the table) to Rosetta Code.

Thanks for the feedback!

Retired Build Engineer

1 Like