with Ada.Text_Io, Ada.Integer_Text_Io;
use Ada.Text_Io, Ada.Integer_Text_Io;
procedure Entiers is
N : constant Natural := 50;
type TblEntiers is array (1..N) of Integer;
type EntierSouple is record
Data : TblEntiers;
Positif : Boolean := True;
end record;
Zero : constant EntierSouple := ((others => 0), True);
Un : constant EntierSouple := ((N => 1, others => 0), True);
function Integer2EntierSouple(A : in Integer) return EntierSouple is
Res : EntierSouple := Zero;
I : Integer;
Tmp : Integer := A;
begin
if (Tmp < 0) then
Tmp := -Tmp;
Res.Positif := False;
end if;
I := TblEntiers'Last;
while (Tmp > 0) loop
Res.Data(I) := Tmp mod 10;
Tmp := Tmp / 10;
I := I - 1;
end loop;
return Res;
end;
procedure Put(A : in EntierSouple) is
Print : Boolean := False;
begin
if not A.Positif then
Put('-');
end if;
for I in TblEntiers'Range loop
if A.Data(I) /= 0 then
Print := True;
end if;
if Print then
Put(A.Data(I), 1);
end if;
end loop;
if not Print then
Put('0');
end if;
end;
function "<"(A, B : in EntierSouple) return Boolean is
begin
if A.Positif /= B.Positif then
return not A.Positif;
end if;
if A.Positif then
for I in TblEntiers'Range loop
if A.Data(I) > B.Data(I) then
return False;
elsif A.Data(I) < B.Data(I) then
return True;
end if;
end loop;
else
for I in TblEntiers'Range loop
if A.Data(I) < B.Data(I) then
return False;
elsif A.Data(I) > B.Data(I) then
return True;
end if;
end loop;
end if;
return false; -- ie a = b
end;
function "="(A, B : in EntierSouple) return Boolean is
begin
if A.Positif /= B.Positif then
return False;
end if;
for I in TblEntiers'Range loop
if (A.Data(I) /= B.Data(I)) then
return False;
end if;
end loop;
return True;
end;
function "<="(A, B : in EntierSouple) return Boolean is
begin
return A < B or A = B;
end;
function ">="(A, B : in EntierSouple) return Boolean is
begin
return not (A < B);
end;
function ">"(A, B : in EntierSouple) return Boolean is
begin
return not (A < B) and A /= B;
end;
function "+"(A, B : in EntierSouple) return EntierSouple is
Res : EntierSouple := Zero;
Ret : Integer := 0;
PA, PB, Tmp : EntierSouple;
begin
if A.Positif = B.Positif then
Res.Positif := A.Positif;
for I in reverse TblEntiers'Range loop
Ret := A.Data(I) + B.Data(I) + Ret;
Res.Data(I) := Ret mod 10;
Ret := Ret / 10;
end loop;
else
PA := A;
PA.Positif := True;
PB := B;
PB.Positif := True;
if PA < PB then
Tmp := PA;
PA := PB;
PB := Tmp;
Res.Positif := B.Positif;
else
Res.Positif := A.Positif;
end if;
for I in reverse TblEntiers'Range loop
Ret := PA.Data(I) - PB.Data(I) - Ret;
if Ret < 0 then
Res.Data(I) := Ret + 10;
Ret := 1;
else
Res.Data(I) := Ret;
Ret := 0;
end if;
end loop;
end if;
return Res;
end;
function "-"(A, B : in EntierSouple) return EntierSouple is
begin
return A + (B.Data, not B.Positif);
end;
procedure Inc(A : in out EntierSouple) is
I : EntierSouple := Integer2EntierSouple(1);
begin
A := A + I;
end;
function "*"(A, B : in EntierSouple) return EntierSouple is
Res : EntierSouple := Zero;
Tmp : EntierSouple := Zero;
begin
if (A < B) then
while Tmp /= A loop
Res := Res + B;
Inc(Tmp);
end loop;
else
while Tmp /= B loop
Res := Res + A;
Inc(Tmp);
end loop;
end if;
return Res;
end;
-- ici a et b > 0 !!!!!
function "mod"(A, B : in EntierSouple) return EntierSouple is
Tmp : EntierSouple := A;
begin
while Tmp >= B loop
Tmp := Tmp - B;
end loop;
return Tmp;
end;
-- ici a et b > 0 !!!!!
function "/"(A, B : in EntierSouple) return EntierSouple is
Tmp : EntierSouple := A;
Div : EntierSouple := Zero;
begin
while Tmp >= B loop
Tmp := Tmp - B;
Div := Div + Un;
end loop;
return Div;
end;
begin
Put(Integer2EntierSouple(45687)); New_Line;
New_Line;
Put(Integer2EntierSouple(45687)
+ Integer2EntierSouple(45687)); Put(" -- ");
Put(45687 + 45687, 0); New_Line;
New_Line;
Put(Integer2EntierSouple(45687) * Integer2EntierSouple(45687) * Integer2EntierSouple(45687)); New_Line;
-- Put(45687 * 45687 * 45687);
New_Line;
Put("1-10 : ");
Put(Integer2EntierSouple(1)
- Integer2EntierSouple(10)); Put(" -- ");
Put(1-10); New_Line;
New_Line;
Put("45687 - 456870 : ");
Put(Integer2EntierSouple(45687)
- Integer2EntierSouple(456870)); Put(" -- ");
Put(45687 - 456870, 0); New_Line;
New_Line;
Put("456870 - 45687 : ");
Put(Integer2EntierSouple(456870)
- Integer2EntierSouple(45687)); Put(" -- ");
Put(456870 - 45687, 0); New_Line;
Put("456873 mod 45687 : ");
Put(Integer2EntierSouple(456873)
mod Integer2EntierSouple(45687)); Put(" -- "); New_Line;
Put("456873 / 45687 : ");
Put(Integer2EntierSouple(456873)
/ Integer2EntierSouple(45687)); Put(" -- "); New_Line;
end;