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 = 0x1p100;
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);