]> git.ipfire.org Git - thirdparty/glibc.git/blame - math/test-fenvinline.c
Fix trailing space.
[thirdparty/glibc.git] / math / test-fenvinline.c
CommitLineData
85b29045
AZ
1/* Test for fenv inline implementations.
2 Copyright (C) 2015 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
18
19#ifndef _GNU_SOURCE
20# define _GNU_SOURCE
21#endif
22
23/* To make sure the fenv inline function are used. */
24#undef __NO_MATH_INLINES
25
26#include <fenv.h>
27#include <stdio.h>
28#include <math-tests.h>
29
30/*
31 Since not all architectures might define all exceptions, we define
32 a private set and map accordingly.
33*/
34#define NO_EXC 0
35#define INEXACT_EXC 0x1
36#define DIVBYZERO_EXC 0x2
37#define UNDERFLOW_EXC 0x04
38#define OVERFLOW_EXC 0x08
39#define INVALID_EXC 0x10
40#define ALL_EXC \
41 (INEXACT_EXC | DIVBYZERO_EXC | UNDERFLOW_EXC | OVERFLOW_EXC | \
42 INVALID_EXC)
43static int count_errors;
44
45#if FE_ALL_EXCEPT
46static void
47test_single_exception_fp_int (int exception,
48 int exc_flag,
49 int fe_flag,
50 const char *flag_name)
51{
52 if (exception & exc_flag)
53 {
54 if (fetestexcept (fe_flag))
55 printf (" Pass: Exception \"%s\" is set\n", flag_name);
56 else
57 {
58 printf (" Fail: Exception \"%s\" is not set\n", flag_name);
59 ++count_errors;
60 }
61 }
62 else
63 {
64 if (fetestexcept (fe_flag))
65 {
66 printf (" Fail: Exception \"%s\" is set\n", flag_name);
67 ++count_errors;
68 }
69 else
70 printf (" Pass: Exception \"%s\" is not set\n", flag_name);
71 }
72}
73/* Test whether a given exception was raised. */
74static void
75test_single_exception_fp_double (int exception,
76 int exc_flag,
77 double fe_flag,
78 const char *flag_name)
79{
80 if (exception & exc_flag)
81 {
82 if (fetestexcept (fe_flag))
83 printf (" Pass: Exception \"%s\" is set\n", flag_name);
84 else
85 {
86 printf (" Fail: Exception \"%s\" is not set\n", flag_name);
87 ++count_errors;
88 }
89 }
90 else
91 {
92 if (fetestexcept (fe_flag))
93 {
94 printf (" Fail: Exception \"%s\" is set\n", flag_name);
95 ++count_errors;
96 }
97 else
98 printf (" Pass: Exception \"%s\" is not set\n", flag_name);
99 }
100}
101#endif
102
103static void
104test_exceptions (const char *test_name, int exception)
105{
106 printf ("Test: %s\n", test_name);
107#ifdef FE_DIVBYZERO
108 test_single_exception_fp_double (exception, DIVBYZERO_EXC, FE_DIVBYZERO,
109 "DIVBYZERO");
110#endif
111#ifdef FE_INVALID
112 test_single_exception_fp_double (exception, INVALID_EXC, FE_INVALID,
113 "INVALID");
114#endif
115#ifdef FE_INEXACT
116 test_single_exception_fp_double (exception, INEXACT_EXC, FE_INEXACT,
117 "INEXACT");
118#endif
119#ifdef FE_UNDERFLOW
120 test_single_exception_fp_double (exception, UNDERFLOW_EXC, FE_UNDERFLOW,
121 "UNDERFLOW");
122#endif
123#ifdef FE_OVERFLOW
124 test_single_exception_fp_double (exception, OVERFLOW_EXC, FE_OVERFLOW,
125 "OVERFLOW");
126#endif
127}
128
129static void
130test_exceptionflag (void)
131{
132 printf ("Test: fegetexceptionflag (FE_ALL_EXCEPT)\n");
133#if FE_ALL_EXCEPT
134 fexcept_t excepts;
135
136 feclearexcept (FE_ALL_EXCEPT);
137
138 feraiseexcept (FE_INVALID);
139 fegetexceptflag (&excepts, FE_ALL_EXCEPT);
140
141 feclearexcept (FE_ALL_EXCEPT);
142 feraiseexcept (FE_OVERFLOW | FE_INEXACT);
143
144 fesetexceptflag (&excepts, FE_ALL_EXCEPT);
145
146 test_single_exception_fp_int (INVALID_EXC, INVALID_EXC, FE_INVALID,
147 "INVALID (int)");
148 test_single_exception_fp_int (INVALID_EXC, OVERFLOW_EXC, FE_OVERFLOW,
149 "OVERFLOW (int)");
150 test_single_exception_fp_int (INVALID_EXC, INEXACT_EXC, FE_INEXACT,
151 "INEXACT (int)");
152
153 /* Same test, but using double as argument */
154 feclearexcept (FE_ALL_EXCEPT);
155
156 feraiseexcept (FE_INVALID);
157 fegetexceptflag (&excepts, (double)FE_ALL_EXCEPT);
158
159 feclearexcept (FE_ALL_EXCEPT);
160 feraiseexcept (FE_OVERFLOW | FE_INEXACT);
161
162 fesetexceptflag (&excepts, (double)FE_ALL_EXCEPT);
163
164 test_single_exception_fp_double (INVALID_EXC, INVALID_EXC, FE_INVALID,
165 "INVALID (double)");
166 test_single_exception_fp_double (INVALID_EXC, OVERFLOW_EXC, FE_OVERFLOW,
167 "OVERFLOW (double)");
168 test_single_exception_fp_double (INVALID_EXC, INEXACT_EXC, FE_INEXACT,
169 "INEXACT (double)");
170#endif
171}
172
173static void
174test_fesetround (void)
175{
176#if defined FE_TONEAREST && defined FE_TOWARDZERO
177 int res1;
178 int res2;
179
180 printf ("Tests for fesetround\n");
181
182 /* The fesetround should not itself cause the test to fail, however it
183 should either succeed for both 'int' and 'double' argument, or fail
184 for both. */
185 res1 = fesetround ((int) FE_TOWARDZERO);
186 res2 = fesetround ((double) FE_TOWARDZERO);
187 if (res1 != res2)
188 {
189 printf ("fesetround (FE_TOWARDZERO) failed: %d, %d\n", res1, res2);
190 ++count_errors;
191 }
192
193 res1 = fesetround ((int) FE_TONEAREST);
194 res2 = fesetround ((double) FE_TONEAREST);
195 if (res1 != res2)
196 {
197 printf ("fesetround (FE_TONEAREST) failed: %d, %d\n", res1, res2);
198 ++count_errors;
199 }
200#endif
201}
202
75413d49 203#if FE_ALL_EXCEPT
85b29045
AZ
204/* Tests for feenableexcept/fedisableexcept. */
205static void
206feenable_test (const char *flag_name, fexcept_t fe_exc)
207{
85b29045
AZ
208 int fe_exci = fe_exc;
209 double fe_excd = fe_exc;
210 int excepts;
211
212 /* First disable all exceptions. */
213 if (fedisableexcept (FE_ALL_EXCEPT) == -1)
214 {
215 printf ("Test: fedisableexcept (FE_ALL_EXCEPT) failed\n");
216 ++count_errors;
217 /* If this fails, the other tests don't make sense. */
218 return;
219 }
220
221 /* Test for inline macros using integer argument. */
222 excepts = feenableexcept (fe_exci);
223 if (!EXCEPTION_ENABLE_SUPPORTED (fe_exci) && excepts == -1)
224 {
225 printf ("Test: not testing feenableexcept, it isn't implemented.\n");
226 return;
227 }
228 if (excepts == -1)
229 {
230 printf ("Test: feenableexcept (%s) failed\n", flag_name);
231 ++count_errors;
232 return;
233 }
234 if (excepts != 0)
235 {
236 printf ("Test: feenableexcept (%s) failed, return should be 0, is %x\n",
237 flag_name, excepts);
238 ++count_errors;
239 }
240
241 /* And now disable the exception again. */
242 excepts = fedisableexcept (fe_exc);
243 if (excepts == -1)
244 {
245 printf ("Test: fedisableexcept (%s) failed\n", flag_name);
246 ++count_errors;
247 return;
248 }
249 if (excepts != fe_exc)
250 {
251 printf ("Test: fedisableexcept (%s) failed, return should be 0x%x, is 0x%x\n",
9e8c0381 252 flag_name, (unsigned int)fe_exc, excepts);
85b29045
AZ
253 ++count_errors;
254 }
255
256 /* Test for inline macros using double argument. */
257 excepts = feenableexcept (fe_excd);
258 if (!EXCEPTION_ENABLE_SUPPORTED (fe_excd) && excepts == -1)
259 {
260 printf ("Test: not testing feenableexcept, it isn't implemented.\n");
261 return;
262 }
263 if (excepts == -1)
264 {
265 printf ("Test: feenableexcept (%s) failed\n", flag_name);
266 ++count_errors;
267 return;
268 }
269 if (excepts != 0)
270 {
271 printf ("Test: feenableexcept (%s) failed, return should be 0, is %x\n",
272 flag_name, excepts);
273 ++count_errors;
274 }
275
276 /* And now disable the exception again. */
277 excepts = fedisableexcept (fe_exc);
278 if (excepts == -1)
279 {
280 printf ("Test: fedisableexcept (%s) failed\n", flag_name);
281 ++count_errors;
282 return;
283 }
284 if (excepts != fe_exc)
285 {
286 printf ("Test: fedisableexcept (%s) failed, return should be 0x%x, is 0x%x\n",
9e8c0381 287 flag_name, (unsigned int)fe_exc, excepts);
85b29045
AZ
288 ++count_errors;
289 }
85b29045 290}
75413d49 291#endif
85b29045
AZ
292
293static void
294test_feenabledisable (void)
295{
296 printf ("Tests for feenableexcepts/fedisableexcept\n");
297
298 /* We might have some exceptions still set. */
299 feclearexcept (FE_ALL_EXCEPT);
300
301#ifdef FE_DIVBYZERO
302 feenable_test ("FE_DIVBYZERO", FE_DIVBYZERO);
303#endif
304#ifdef FE_INVALID
305 feenable_test ("FE_INVALID", FE_INVALID);
306#endif
307#ifdef FE_INEXACT
308 feenable_test ("FE_INEXACT", FE_INEXACT);
309#endif
310#ifdef FE_UNDERFLOW
311 feenable_test ("FE_UNDERFLOW", FE_UNDERFLOW);
312#endif
313#ifdef FE_OVERFLOW
314 feenable_test ("FE_OVERFLOW", FE_OVERFLOW);
315#endif
316 fesetenv (FE_DFL_ENV);
317}
318
319static int
320do_test (void)
321{
322 /* clear all exceptions and test if all are cleared */
323 feclearexcept (FE_ALL_EXCEPT);
324 test_exceptions ("feclearexcept (FE_ALL_EXCEPT) clears all exceptions",
325 NO_EXC);
326
327 /* raise all exceptions and test if all are raised */
328 feraiseexcept (FE_ALL_EXCEPT);
329 test_exceptions ("feraiseexcept (FE_ALL_EXCEPT) raises all exceptions",
330 ALL_EXC);
331
332 /* Same test, but using double as argument */
333 feclearexcept ((double)FE_ALL_EXCEPT);
334 test_exceptions ("feclearexcept ((double)FE_ALL_EXCEPT) clears all exceptions",
335 NO_EXC);
336
337 feraiseexcept ((double)FE_ALL_EXCEPT);
338 test_exceptions ("feraiseexcept ((double)FE_ALL_EXCEPT) raises all exceptions",
339 ALL_EXC);
340
341 test_exceptionflag ();
342
343 test_fesetround ();
344
345 test_feenabledisable ();
346
347 return count_errors;
348}
349
350#define TEST_FUNCTION do_test ()
351#include "../test-skeleton.c"