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 error("feraiseexcept(%s) want %d got %d\n",
58 te
[i
].name
, te
[i
].i
, r
);
61 r
= feraiseexcept(FE_ALL_EXCEPT
);
63 error("feraisexcept(FE_ALL_EXCEPT) failed\n");
66 error("fegetenv(&env) = %d\n", r
);
67 r
= fetestexcept(FE_ALL_EXCEPT
);
68 if (r
!= FE_ALL_EXCEPT
)
69 error("fetestexcept failed: got 0x%x, want 0x%x (FE_ALL_ECXEPT)\n", r
, FE_ALL_EXCEPT
);
70 r
= fesetenv(FE_DFL_ENV
);
72 error("fesetenv(FE_DFL_ENV) = %d\n", r
);
73 r
= fetestexcept(FE_ALL_EXCEPT
);
75 error("fesetenv(FE_DFL_ENV) did not clear exceptions: 0x%x\n", r
);
78 error("fesetenv(&env) = %d\n", r
);
79 r
= fetestexcept(FE_ALL_EXCEPT
);
80 if (r
!= FE_ALL_EXCEPT
)
81 error("fesetenv(&env) did not restore exceptions: 0x%x\n", r
);
100 static void test_round()
102 #pragma STDC FENV_ACCESS ON
105 volatile float two100
= 0x1p
100;
108 for (i
=0; i
< sizeof tr
/sizeof*tr
; i
++) {
110 error("%s (%d) < 0\n", tr
[i
].name
, tr
[i
].i
);
111 for (r
=0; r
< i
; r
++)
112 if (tr
[r
].i
== tr
[i
].i
)
113 error("%s (%d) == %s (%d)\n",
114 tr
[r
].name
, tr
[r
].i
, tr
[i
].name
, tr
[i
].i
);
117 for (i
=0; i
< sizeof tr
/sizeof*tr
; i
++) {
118 r
= fesetround(tr
[i
].i
);
120 error("fesetround(%s) = %d\n", tr
[i
].name
, r
);
123 error("fegetround() = 0x%x, wanted 0x%x (%s)\n", r
, tr
[i
].i
, tr
[i
].name
);
127 r
= fesetround(FE_UPWARD
);
129 error("fesetround(FE_UPWARD) failed\n");
133 error("fegetenv(&env) = %d\n", r
);
135 r
= fesetenv(FE_DFL_ENV
);
137 error("fesetenv(FE_DFL_ENV) = %d\n", r
);
139 if (r
!= FE_TONEAREST
)
140 error("fesetenv(FE_DFL_ENV) did not set FE_TONEAREST (0x%x), got 0x%x\n", FE_TONEAREST
, r
);
143 error("fesetenv(FE_DFL_ENV) did not set FE_TONEAREST, arithmetics rounds upward\n");
146 error("fesetenv(FE_DFL_ENV) did not set FE_TONEAREST, arithmetics rounds downward or tozero\n");
149 error("fesetenv(&env) = %d\n", r
);
152 error("fesetenv(&env) did not restore 0x%x, got 0x%x\n", i
, r
);
156 error("fesetenv did not restore upward rounding\n");
161 /* ieee double precision add operation */
162 static struct dd_d t
[] = {
163 T(RN
, 0x1p
+0, 0x1p
-52, 0x1.0000000000001p
+0, 0x0p
+0, 0)
164 T(RN
, 0x1p
+0, 0x1p
-53, 0x1p
+0, -0x1p
-1, INEXACT
)
165 T(RN
, 0x1p
+0, 0x1.01p
-53, 0x1.0000000000001p
+0, 0x1.fep
-2, INEXACT
)
166 T(RN
, 0x1p
+0, -0x1p
-54, 0x1p
+0, 0x1p
-2, INEXACT
)
167 T(RN
, 0x1p
+0, -0x1.01p
-54, 0x1.fffffffffffffp
-1, -0x1.fep
-2, INEXACT
)
168 T(RN
, -0x1p
+0, -0x1p
-53, -0x1p
+0, 0x1p
-1, INEXACT
)
169 T(RN
, -0x1p
+0, -0x1.01p
-53, -0x1.0000000000001p
+0, -0x1.fep
-2, INEXACT
)
170 T(RN
, -0x1p
+0, 0x1p
-54, -0x1p
+0, -0x1p
-2, INEXACT
)
171 T(RN
, -0x1p
+0, 0x1.01p
-54, -0x1.fffffffffffffp
-1, 0x1.fep
-2, INEXACT
)
173 T(RU
, 0x1p
+0, 0x1p
-52, 0x1.0000000000001p
+0, 0x0p
+0, 0)
174 T(RU
, 0x1p
+0, 0x1p
-53, 0x1.0000000000001p
+0, 0x1p
-1, INEXACT
)
175 T(RU
, 0x1p
+0, 0x1.01p
-53, 0x1.0000000000001p
+0, 0x1.fep
-2, INEXACT
)
176 T(RU
, 0x1p
+0, -0x1p
-54, 0x1p
+0, 0x1p
-2, INEXACT
)
177 T(RU
, 0x1p
+0, -0x1.01p
-54, 0x1p
+0, 0x1.01p
-2, INEXACT
)
178 T(RU
, -0x1p
+0, -0x1p
-53, -0x1p
+0, 0x1p
-1, INEXACT
)
179 T(RU
, -0x1p
+0, -0x1.01p
-53, -0x1p
+0, 0x1.01p
-1, INEXACT
)
180 T(RU
, -0x1p
+0, 0x1p
-54, -0x1.fffffffffffffp
-1, 0x1p
-1, INEXACT
)
181 T(RU
, -0x1p
+0, 0x1.01p
-54, -0x1.fffffffffffffp
-1, 0x1.fep
-2, INEXACT
)
183 T(RD
, 0x1p
+0, 0x1p
-52, 0x1.0000000000001p
+0, 0x0p
+0, 0)
184 T(RD
, 0x1p
+0, 0x1p
-53, 0x1p
+0, -0x1p
-1, INEXACT
)
185 T(RD
, 0x1p
+0, 0x1.01p
-53, 0x1p
+0, -0x1.01p
-1, INEXACT
)
186 T(RD
, 0x1p
+0, -0x1p
-54, 0x1.fffffffffffffp
-1, -0x1p
-1, INEXACT
)
187 T(RD
, 0x1p
+0, -0x1.01p
-54, 0x1.fffffffffffffp
-1, -0x1.fep
-2, INEXACT
)
188 T(RD
, -0x1p
+0, -0x1p
-53, -0x1.0000000000001p
+0, -0x1p
-1, INEXACT
)
189 T(RD
, -0x1p
+0, -0x1.01p
-53, -0x1.0000000000001p
+0, -0x1.fep
-2, INEXACT
)
190 T(RD
, -0x1p
+0, 0x1p
-54, -0x1p
+0, -0x1p
-2, INEXACT
)
191 T(RD
, -0x1p
+0, 0x1.01p
-54, -0x1p
+0, -0x1.01p
-2, INEXACT
)
193 T(RZ
, 0x1p
+0, 0x1p
-52, 0x1.0000000000001p
+0, 0x0p
+0, 0)
194 T(RZ
, 0x1p
+0, 0x1p
-53, 0x1p
+0, -0x1p
-1, INEXACT
)
195 T(RZ
, 0x1p
+0, 0x1.01p
-53, 0x1p
+0, -0x1.01p
-1, INEXACT
)
196 T(RZ
, 0x1p
+0, -0x1p
-54, 0x1.fffffffffffffp
-1, -0x1p
-1, INEXACT
)
197 T(RZ
, 0x1p
+0, -0x1.01p
-54, 0x1.fffffffffffffp
-1, -0x1.fep
-2, INEXACT
)
198 T(RZ
, -0x1p
+0, -0x1p
-53, -0x1p
+0, 0x1p
-1, INEXACT
)
199 T(RZ
, -0x1p
+0, -0x1.01p
-53, -0x1p
+0, 0x1.01p
-1, INEXACT
)
200 T(RZ
, -0x1p
+0, 0x1p
-54, -0x1.fffffffffffffp
-1, 0x1p
-1, INEXACT
)
201 T(RZ
, -0x1p
+0, 0x1.01p
-54, -0x1.fffffffffffffp
-1, 0x1.fep
-2, INEXACT
)
204 static void test_round_add(void)
206 #pragma STDC FENV_ACCESS ON
212 for (i
= 0; i
< sizeof t
/sizeof *t
; i
++) {
219 d
= ulperr(y
, p
->y
, p
->dy
);
220 if (!checkcr(y
, p
->y
, p
->r
)) {
221 printf("%s:%d: %s %a+%a want %a got %a ulperr %.3f = %a + %a\n",
222 p
->file
, p
->line
, rstr(p
->r
), p
->x
, p
->x2
, p
->y
, y
, d
, d
-p
->dy
, p
->dy
);
228 static void test_bad(void)
233 r
= feclearexcept(FE_ALL_EXCEPT
);
235 error("feclearexcept(FE_ALL_EXCEPT) failed\n");
236 r
= fetestexcept(-1);
238 error("fetestexcept(-1) should return 0 when all exceptions are cleared, got %d\n", r
);
239 r
= feraiseexcept(1234567|FE_ALL_EXCEPT
);
241 error("feraiseexcept returned non-zero for non-supported exceptions: %d\n", r
);
242 r
= feclearexcept(1234567|FE_ALL_EXCEPT
);
244 error("feclearexcept returned non-zero for non-supported exceptions: %d\n", r
);
245 r
= fesetround(1234567);
247 error("fesetround should fail on invalid rounding mode\n");
248 r
= fegetexceptflag(&f
, 1234567);
250 error("fegetexceptflag returned non-zero for non-supported exceptions: %d\n", r
);
251 r
= fegetexceptflag(&f
, 0);
253 error("fegetexceptflag(0) failed\n");
254 r
= fesetexceptflag(&f
, 1234567);
256 error("fesetexceptflag returned non-zero fir non-supported exceptions: %d\n", r
);