> i386 only, might be related
>
> ,.,. CXG2021 ACATS 2.5 13-05-27 17:47:57
> ---- CXG2021 Check the accuracy of the complex SIN and COS functions.
> * CXG2021 Identity_2_Test 3 0: Cos(( 1.60300E+01, 1.60000E+01))
> imaginary part actual: 1.40623E+06 expected:
> 1.40622E+06 difference: 4.00000E+00 max err:
> 3.68797E+00 efactor: 1.40623E+06.
> **** CXG2021 FAILED ****************************.
The test fails because the difference (4.00000E+00) is larger than the max err
(3.68797E+00). I've reduced the testcase to p.adb, which reads in part:
package Complex_Type is new Ada.Numerics.Generic_Complex_Types (Float);
use Complex_Type;
package CEF is
new Ada.Numerics.Generic_Complex_Elementary_Functions (Complex_Type);
function Sin (X : Complex) return Complex renames CEF.Sin;
function Cos (X : Complex) return Complex renames CEF.Cos;
Z : Complex;
W : constant Complex := (0.0625, 0.0625);
ZmW : Complex;
Sin_ZmW, Cos_ZmW : Complex;
A1, A2 : Complex;
Sin_W : constant Complex := (6.2581348413276935585E-2,
6.2418588008436587236E-2);
Cos_W_m_1 : constant Complex := (-2.5431314180235545803E-6,
-3.9062493377261771826E-3);
begin
for I in 2 .. 3 loop
Z := (16.0 + Float (I) / Float (100), 16.0);
ZmW := Z - W;
Cos_ZmW := Cos (ZmW);
and most of the 4.00000E+00 difference for I = 3 in the final result comes
from Im (Cos_ZmW), which in turn comes from Re (ZmW). We have at -O1:
(gdb) x/f ($esp)
0xffffce60: 16.0300007
(gdb) x/f ($esp + 8)
0xffffce68: 0.0625
(gdb) nexti
0x0804a2e6 2791 zmw := p__complex_type__Osubtract__2 (z, w);
(gdb) p/f $eax
$1 = 15.9675007 <========= Re (ZmW)
and we have at -O2:
(gdb) info reg st0
st0 0.0625 (raw 0x3ffb8000000000000000)
(gdb) info reg st1
st1 16.030000000000000000624500451351651 (raw
0x4003803d70a3d70a3d71)
(gdb) nexti
0x0804a231 520 re => left.re - right.re,
(gdb) info reg st0
st0 15.967500000000000000624500451351651 (raw
0x4002ff7ae147ae147ae2)
(gdb) nexti
(gdb) x/f ($ebp - 0x44)
0xffffce94: 15.9674997 <========= Re (ZmW)
with Im (Zmw) the same (15.9375) in both cases. At a result, Im (Cos_ZmW) is
1071153.38 at -O1 and 1071149.5 at -O2, the difference (3.88) being already
larger than the max err.
IOW most of the difference only comes from:
16.0 + Float (I) / Float (100) - 0.0625
where we truncate to 32-bit at -O1 before doing the subtraction, whereas we
keep the Extended Precision at -O2, and then goes through the exponentation,
leading to the final 3.88 difference.
Fixed thusly, tested on i686-suse-linux, applied on the mainline.
2013-05-31 Eric Botcazou <ebotca...@adacore.com>
* ada/acats/floatstore.lst: New.
* ada/acats/run_all.sh: Process it.
--
Eric Botcazou
with Text_IO; use Text_IO;
with Ada.Numerics.Generic_Complex_Types;
with Ada.Numerics.Generic_Complex_Elementary_Functions;
procedure P is
package Complex_Type is new Ada.Numerics.Generic_Complex_Types (Float);
use Complex_Type;
package CEF is
new Ada.Numerics.Generic_Complex_Elementary_Functions (Complex_Type);
function Sin (X : Complex) return Complex renames CEF.Sin;
function Cos (X : Complex) return Complex renames CEF.Cos;
Z : Complex;
W : constant Complex := (0.0625, 0.0625);
ZmW : Complex;
Sin_ZmW, Cos_ZmW : Complex;
A1, A2 : Complex;
Sin_W : constant Complex := (6.2581348413276935585E-2,
6.2418588008436587236E-2);
Cos_W_m_1 : constant Complex := (-2.5431314180235545803E-6,
-3.9062493377261771826E-3);
begin
for I in 2 .. 3 loop
Z := (16.0 + Float (I) / Float (100), 16.0);
ZmW := Z - W;
Sin_ZmW := Sin (ZmW);
Cos_ZmW := Cos (ZmW);
A1 := Cos (Z);
A2 := Cos_ZmW + (Cos_ZmW * Cos_W_m_1 - Sin_ZmW * Sin_W);
Put_Line (" actual: " & A1.Im'Img & " | expected: " & A2.Im'Img);
end loop;
end;
Index: ada/acats/run_all.sh
===================================================================
--- ada/acats/run_all.sh (revision 199343)
+++ ada/acats/run_all.sh (working copy)
@@ -225,6 +225,10 @@ for chapter in $chapters; do
if [ $? -eq 0 ]; then
extraflags="$extraflags -gnatE"
fi
+ grep $i $testdir/floatstore.lst > /dev/null 2>&1
+ if [ $? -eq 0 ]; then
+ extraflags="$extraflags -ffloat-store"
+ fi
grep $i $testdir/stackcheck.lst > /dev/null 2>&1
if [ $? -eq 0 ]; then
extraflags="$extraflags -fstack-check"
Index: ada/acats/floatstore.lst
===================================================================
--- ada/acats/floatstore.lst (revision 0)
+++ ada/acats/floatstore.lst (revision 0)
@@ -0,0 +1 @@
+cxg2021