Hi;
There is a Rosetta Code task written in Ada located at:
which references a package (“Base_Conversion”) I don’t see bundled with the GNAT Ada compiler and I don’t see elsewhere on the Rosetta Code web site.
However, in the Rosetta Code Task located at:
there are two functions defined as part of the task which perform the work the package I want to write.
So I tried to leverage the two functions into a package spec and a package body, with the calls to the two functions placed in a test driver.
I obviously do not sufficiently understand what is required in the spec to make this work correctly.
Here are my error messages from the attempt to compile the driver code:
gnatmake ./test_number_base_conversion.adb
gcc -c -I./ -I- ./test_number_base_conversion.adb
gcc -c -I./ -I- ./base_conversion.adb
base_conversion.adb:5:04: error: “Max_Base” conflicts with declaration at base_conversion.ads:5
base_conversion.adb:6:12: error: “Base_Type” conflicts with declaration at base_conversion.ads:6
gnatmake: “./base_conversion.adb” compilation error
The Ada code I have written is enclosed below.
Thanks,
Retired Build Engineer
with Ada.Text_IO; use Ada.Text_IO;
with Base_Conversion; use Base_Conversion;
procedure Test_Number_Base_Conversion is
begin
Put_Line ("26 converted to base 16 is " & To_Base (26, 16));
Put_Line
("1a (base 16) is decimal" & Integer'Image (To_Decimal ("1a", 16)));
end Test_Number_Base_Conversion;
with Ada.Strings.Fixed;
with Ada.Strings.Unbounded;
package Base_Conversion is
Max_Base : constant := 36;
subtype Base_Type is Integer range 2 .. Max_Base;
function To_Decimal (Value : String; Base : Base_Type) return Integer;
function To_Base (Value : Natural; Base : Base_Type) return String;
end Base_Conversion;
with Ada.Strings.Fixed;
with Ada.Strings.Unbounded;
package body Base_Conversion is
Max_Base : constant := 36;
subtype Base_Type is Integer range 2 .. Max_Base;
Num_Digits : constant String := "0123456789abcdefghijklmnopqrstuvwxyz";
Invalid_Digit : exception;
function To_Decimal (Value : String; Base : Base_Type) return Integer is
use Ada.Strings.Fixed;
Result : Integer := 0;
Decimal_Value : Integer;
Radix_Offset : Natural := 0;
begin
for I in reverse Value'Range loop
Decimal_Value := Index (Num_Digits, Value (I .. I)) - 1;
if Decimal_Value < 0 then
raise Invalid_Digit;
end if;
Result := Result + (Base**Radix_Offset * Decimal_Value);
Radix_Offset := Radix_Offset + 1;
end loop;
return Result;
end To_Decimal;
function To_Base (Value : Natural; Base : Base_Type) return String is
use Ada.Strings.Unbounded;
Result : Unbounded_String := Null_Unbounded_String;
Temp : Natural := Value;
Base_Digit : String (1 .. 1);
begin
if Temp = 0 then
return "0";
end if;
while Temp > 0 loop
Base_Digit (1) := Num_Digits ((Temp mod Base) + 1);
if Result = Null_Unbounded_String then
Append (Result, Base_Digit);
else
Insert (Source => Result, Before => 1, New_Item => Base_Digit);
end if;
Temp := Temp / Base;
end loop;
return To_String (Result);
end To_Base;
end Base_Conversion;