6 static int test_status
;
8 #define error(...) print(__FILE__, __LINE__, __VA_ARGS__)
9 static void print(char *f
, int l
, char *fmt
, ...)
13 printf("%s:%d: ", f
, l
);
43 static void test_except()
45 #pragma STDC FENV_ACCESS ON
49 for (i
=0; te
[i
].i
; i
++) {
50 feclearexcept(FE_ALL_EXCEPT
);
52 r
= feraiseexcept(te
[i
].i
);
54 error("feraiseexcept(%s) returned %d\n", te
[i
].name
, r
);
55 r
= fetestexcept(FE_ALL_EXCEPT
);
57 #if defined FE_OVERFLOW && defined FE_INEXACT
58 if (te
[i
].i
== FE_OVERFLOW
&& r
== (FE_OVERFLOW
|FE_INEXACT
))
61 #if defined FE_UNDERFLOW && defined FE_INEXACT
62 if (te
[i
].i
== FE_UNDERFLOW
&& r
== (FE_UNDERFLOW
|FE_INEXACT
))
65 error("feraiseexcept(%s) want %d got %d\n",
66 te
[i
].name
, te
[i
].i
, r
);
70 r
= feraiseexcept(FE_ALL_EXCEPT
);
72 error("feraisexcept(FE_ALL_EXCEPT) failed\n");
75 error("fegetenv(&env) = %d\n", r
);
76 r
= fetestexcept(FE_ALL_EXCEPT
);
77 if (r
!= FE_ALL_EXCEPT
)
78 error("fetestexcept failed: got 0x%x, want 0x%x (FE_ALL_ECXEPT)\n", r
, FE_ALL_EXCEPT
);
79 r
= fesetenv(FE_DFL_ENV
);
81 error("fesetenv(FE_DFL_ENV) = %d\n", r
);
82 r
= fetestexcept(FE_ALL_EXCEPT
);
84 error("fesetenv(FE_DFL_ENV) did not clear exceptions: 0x%x\n", r
);
87 error("fesetenv(&env) = %d\n", r
);
88 r
= fetestexcept(FE_ALL_EXCEPT
);
89 if (r
!= FE_ALL_EXCEPT
)
90 error("fesetenv(&env) did not restore exceptions: 0x%x\n", r
);
109 static void test_round()
111 #pragma STDC FENV_ACCESS ON
114 volatile float two100
= 0x1p
100;
117 for (i
=0; i
< sizeof tr
/sizeof*tr
; i
++) {
119 error("%s (%d) < 0\n", tr
[i
].name
, tr
[i
].i
);
120 for (r
=0; r
< i
; r
++)
121 if (tr
[r
].i
== tr
[i
].i
)
122 error("%s (%d) == %s (%d)\n",
123 tr
[r
].name
, tr
[r
].i
, tr
[i
].name
, tr
[i
].i
);
126 for (i
=0; i
< sizeof tr
/sizeof*tr
; i
++) {
127 r
= fesetround(tr
[i
].i
);
129 error("fesetround(%s) = %d\n", tr
[i
].name
, r
);
132 error("fegetround() = 0x%x, wanted 0x%x (%s)\n", r
, tr
[i
].i
, tr
[i
].name
);
136 r
= fesetround(FE_UPWARD
);
138 error("fesetround(FE_UPWARD) failed\n");
142 error("fegetenv(&env) = %d\n", r
);
144 r
= fesetenv(FE_DFL_ENV
);
146 error("fesetenv(FE_DFL_ENV) = %d\n", r
);
148 if (r
!= FE_TONEAREST
)
149 error("fesetenv(FE_DFL_ENV) did not set FE_TONEAREST (0x%x), got 0x%x\n", FE_TONEAREST
, r
);
152 error("fesetenv(FE_DFL_ENV) did not set FE_TONEAREST, arithmetics rounds upward\n");
155 error("fesetenv(FE_DFL_ENV) did not set FE_TONEAREST, arithmetics rounds downward or tozero\n");
158 error("fesetenv(&env) = %d\n", r
);
161 error("fesetenv(&env) did not restore 0x%x, got 0x%x\n", i
, r
);
165 error("fesetenv did not restore upward rounding\n");
170 /* ieee double precision add operation */
171 static struct dd_d t
[] = {
172 T(RN
, 0x1p
+0, 0x1p
-52, 0x1.0000000000001p
+0, 0x0p
+0, 0)
173 T(RN
, 0x1p
+0, 0x1p
-53, 0x1p
+0, -0x1p
-1, INEXACT
)
174 T(RN
, 0x1p
+0, 0x1.01p
-53, 0x1.0000000000001p
+0, 0x1.fep
-2, INEXACT
)
175 T(RN
, 0x1p
+0, -0x1p
-54, 0x1p
+0, 0x1p
-2, INEXACT
)
176 T(RN
, 0x1p
+0, -0x1.01p
-54, 0x1.fffffffffffffp
-1, -0x1.fep
-2, INEXACT
)
177 T(RN
, -0x1p
+0, -0x1p
-53, -0x1p
+0, 0x1p
-1, INEXACT
)
178 T(RN
, -0x1p
+0, -0x1.01p
-53, -0x1.0000000000001p
+0, -0x1.fep
-2, INEXACT
)
179 T(RN
, -0x1p
+0, 0x1p
-54, -0x1p
+0, -0x1p
-2, INEXACT
)
180 T(RN
, -0x1p
+0, 0x1.01p
-54, -0x1.fffffffffffffp
-1, 0x1.fep
-2, INEXACT
)
182 T(RU
, 0x1p
+0, 0x1p
-52, 0x1.0000000000001p
+0, 0x0p
+0, 0)
183 T(RU
, 0x1p
+0, 0x1p
-53, 0x1.0000000000001p
+0, 0x1p
-1, INEXACT
)
184 T(RU
, 0x1p
+0, 0x1.01p
-53, 0x1.0000000000001p
+0, 0x1.fep
-2, INEXACT
)
185 T(RU
, 0x1p
+0, -0x1p
-54, 0x1p
+0, 0x1p
-2, INEXACT
)
186 T(RU
, 0x1p
+0, -0x1.01p
-54, 0x1p
+0, 0x1.01p
-2, INEXACT
)
187 T(RU
, -0x1p
+0, -0x1p
-53, -0x1p
+0, 0x1p
-1, INEXACT
)
188 T(RU
, -0x1p
+0, -0x1.01p
-53, -0x1p
+0, 0x1.01p
-1, INEXACT
)
189 T(RU
, -0x1p
+0, 0x1p
-54, -0x1.fffffffffffffp
-1, 0x1p
-1, INEXACT
)
190 T(RU
, -0x1p
+0, 0x1.01p
-54, -0x1.fffffffffffffp
-1, 0x1.fep
-2, INEXACT
)
192 T(RD
, 0x1p
+0, 0x1p
-52, 0x1.0000000000001p
+0, 0x0p
+0, 0)
193 T(RD
, 0x1p
+0, 0x1p
-53, 0x1p
+0, -0x1p
-1, INEXACT
)
194 T(RD
, 0x1p
+0, 0x1.01p
-53, 0x1p
+0, -0x1.01p
-1, INEXACT
)
195 T(RD
, 0x1p
+0, -0x1p
-54, 0x1.fffffffffffffp
-1, -0x1p
-1, INEXACT
)
196 T(RD
, 0x1p
+0, -0x1.01p
-54, 0x1.fffffffffffffp
-1, -0x1.fep
-2, INEXACT
)
197 T(RD
, -0x1p
+0, -0x1p
-53, -0x1.0000000000001p
+0, -0x1p
-1, INEXACT
)
198 T(RD
, -0x1p
+0, -0x1.01p
-53, -0x1.0000000000001p
+0, -0x1.fep
-2, INEXACT
)
199 T(RD
, -0x1p
+0, 0x1p
-54, -0x1p
+0, -0x1p
-2, INEXACT
)
200 T(RD
, -0x1p
+0, 0x1.01p
-54, -0x1p
+0, -0x1.01p
-2, INEXACT
)
202 T(RZ
, 0x1p
+0, 0x1p
-52, 0x1.0000000000001p
+0, 0x0p
+0, 0)
203 T(RZ
, 0x1p
+0, 0x1p
-53, 0x1p
+0, -0x1p
-1, INEXACT
)
204 T(RZ
, 0x1p
+0, 0x1.01p
-53, 0x1p
+0, -0x1.01p
-1, INEXACT
)
205 T(RZ
, 0x1p
+0, -0x1p
-54, 0x1.fffffffffffffp
-1, -0x1p
-1, INEXACT
)
206 T(RZ
, 0x1p
+0, -0x1.01p
-54, 0x1.fffffffffffffp
-1, -0x1.fep
-2, INEXACT
)
207 T(RZ
, -0x1p
+0, -0x1p
-53, -0x1p
+0, 0x1p
-1, INEXACT
)
208 T(RZ
, -0x1p
+0, -0x1.01p
-53, -0x1p
+0, 0x1.01p
-1, INEXACT
)
209 T(RZ
, -0x1p
+0, 0x1p
-54, -0x1.fffffffffffffp
-1, 0x1p
-1, INEXACT
)
210 T(RZ
, -0x1p
+0, 0x1.01p
-54, -0x1.fffffffffffffp
-1, 0x1.fep
-2, INEXACT
)
213 static void test_round_add(void)
215 #pragma STDC FENV_ACCESS ON
221 for (i
= 0; i
< sizeof t
/sizeof *t
; i
++) {
228 d
= ulperr(y
, p
->y
, p
->dy
);
229 if (!checkcr(y
, p
->y
, p
->r
)) {
230 printf("%s:%d: %s %a+%a want %a got %a ulperr %.3f = %a + %a\n",
231 p
->file
, p
->line
, rstr(p
->r
), p
->x
, p
->x2
, p
->y
, y
, d
, d
-p
->dy
, p
->dy
);
237 static void test_bad(void)
242 r
= feclearexcept(FE_ALL_EXCEPT
);
244 error("feclearexcept(FE_ALL_EXCEPT) failed\n");
245 r
= fetestexcept(-1);
247 error("fetestexcept(-1) should return 0 when all exceptions are cleared, got %d\n", r
);
248 r
= feraiseexcept(1234567|FE_ALL_EXCEPT
);
250 error("feraiseexcept returned non-zero for non-supported exceptions: %d\n", r
);
251 r
= feclearexcept(1234567|FE_ALL_EXCEPT
);
253 error("feclearexcept returned non-zero for non-supported exceptions: %d\n", r
);
254 r
= fesetround(1234567);
256 error("fesetround should fail on invalid rounding mode\n");
257 r
= fegetexceptflag(&f
, 1234567);
259 error("fegetexceptflag returned non-zero for non-supported exceptions: %d\n", r
);
260 r
= fegetexceptflag(&f
, 0);
262 error("fegetexceptflag(0) failed\n");
263 r
= fesetexceptflag(&f
, 1234567);
265 error("fesetexceptflag returned non-zero fir non-supported exceptions: %d\n", r
);