===================================================================
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
+-- Copyright (C) 1992-2010, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -43,6 +43,12 @@ package body Ada.Numerics.Generic_Comple
---------
function "*" (Left, Right : Complex) return Complex is
+
+ Scale : constant R := R (R'Machine_Radix) ** ((R'Machine_Emax - 1) / 2);
+ -- In case of overflow, scale the operands by the largest power of the
+ -- radix (to avoid rounding error), so that the square of the scale does
+ -- not overflow itself.
+
X : R;
Y : R;
@@ -53,14 +59,19 @@ package body Ada.Numerics.Generic_Comple
-- If either component overflows, try to scale (skip in fast math mode)
if not Standard'Fast_Math then
- if abs (X) > R'Last then
- X := R'(4.0) * (R'(Left.Re / 2.0) * R'(Right.Re / 2.0)
- - R'(Left.Im / 2.0) * R'(Right.Im / 2.0));
+
+ -- ??? the test below is weird, it needs a comment, otherwise I or
+ -- someone else will change it back to R'Last > abs (X) ???
+
+ if not (abs (X) <= R'Last) then
+ X := Scale**2 * ((Left.Re / Scale) * (Right.Re / Scale) -
+ (Left.Im / Scale) * (Right.Im / Scale));
end if;
- if abs (Y) > R'Last then
- Y := R'(4.0) * (R'(Left.Re / 2.0) * R'(Right.Im / 2.0)
- - R'(Left.Im / 2.0) * R'(Right.Re / 2.0));
+ -- ??? same weird test ???
+ if not (abs (Y) <= R'Last) then
+ Y := Scale**2 * ((Left.Re / Scale) * (Right.Im / Scale)
+ + (Left.Im / Scale) * (Right.Re / Scale));
end if;
end if;
@@ -569,7 +580,8 @@ package body Ada.Numerics.Generic_Comple
-- in order to prevent inaccuracies on machines where not all
-- immediate expressions are rounded, such as PowerPC.
- if Re2 > R'Last then
+ -- ??? same weird test, why not Re2 > R'Last ???
+ if not (Re2 <= R'Last) then
raise Constraint_Error;
end if;
@@ -582,7 +594,8 @@ package body Ada.Numerics.Generic_Comple
begin
Im2 := X.Im ** 2;
- if Im2 > R'Last then
+ -- ??? same weird test
+ if not (Im2 <= R'Last) then
raise Constraint_Error;
end if;