There is no need to keep multiplying the result once it saturates to +Inf.
gcc/ada/ChangeLog:
* libgnat/s-powflt.ads (Maxpow_Exact): Minor comment fix.
* libgnat/s-powlfl.ads (Maxpow_Exact): Likewise.
* libgnat/s-powllf.ads (Maxpow_Exact): Likewise.
* libgnat/s-valrea.adb (Large_Powfive) [1 parameter]: Exit the loop
as soon as the result saturates to +Inf.
(Large_Powfive) [2 parameters]: Likewise.
Maxpow_Exact : constant := 10;
-- Largest power of five exactly representable with Float. It is equal to
- -- floor (M * log 2 / log 5), when M is the size of the mantissa (24).
+ -- floor (M * log 2 / log 5), where M is the size of the mantissa (24).
-- It also works for any number of the form 5*(2**N) and in particular 10.
Maxpow : constant := Maxpow_Exact * 2;
Maxpow_Exact : constant := 22;
-- Largest power of five exactly representable with Long_Float. It is equal
- -- to floor (M * log 2 / log 5), when M is the size of the mantissa (53).
+ -- to floor (M * log 2 / log 5), where M is the size of the mantissa (53).
-- It also works for any number of the form 5*(2**N) and in particular 10.
Maxpow : constant := Maxpow_Exact * 2;
Maxpow_Exact : constant :=
(if Long_Long_Float'Machine_Mantissa = 64 then 27 else 22);
-- Largest power of five exactly representable with Long_Long_Float. It is
- -- equal to floor (M * log 2 / log 5), when M is the size of the mantissa
- -- assumed to be either 64 for IEEE Extended or 53 for IEEE Double.
+ -- equal to floor (M * log 2 / log 5), where M is the size of the mantissa
+ -- (assumed to be either 64 for IEEE Extended or 53 for IEEE Double).
-- It also works for any number of the form 5*(2**N) and in particular 10.
Maxpow : constant := Maxpow_Exact * 2;
pragma Import (Ada, Powfive_300);
for Powfive_300'Address use Powfive_300_Address;
+ H : Double_T;
R : Double_T;
E : Natural;
E := Exp - Maxpow;
end if;
+ -- Accumulate 5**Maxpow into R until E <= Maxpow or R saturates to +Inf
+
while E > Maxpow loop
+ H := R;
R := R * Powfive (Maxpow);
+ if R = H then
+ E := Maxpow;
+ exit;
+ end if;
E := E - Maxpow;
end loop;
pragma Import (Ada, Powfive);
for Powfive'Address use Powfive_Address;
+ H : Double_T;
R : Double_T;
E : Natural;
S := 0;
end if;
+ -- Accumulate 5**Maxpow into R until E <= Maxpow or R saturates to +Inf
+
while E > Maxpow loop
+ H := R;
R := R * Powfive (Maxpow);
+ if R = H then
+ E := Maxpow;
+ exit;
+ end if;
E := E - Maxpow;
end loop;