]> sourceware.org Git - glibc.git/blob - math/libm-test-driver.c
Move non-function-specific parts of libm-test.inc to separate file.
[glibc.git] / math / libm-test-driver.c
1 /* Support code for testing libm functions.
2 Copyright (C) 1997-2017 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 /* Part of testsuite for libm.
20
21 libm-test.inc is processed by a perl script. The resulting file has to
22 be included by a master file that defines:
23
24 Macros:
25 FUNC(function): converts general function name (like cos) to
26 name with correct suffix (e.g. cosl or cosf)
27 FLOAT: floating point type to test
28 - TEST_MSG: informal message to be displayed
29 chooses one of the parameters as delta for testing
30 equality
31 PREFIX A macro which defines the prefix for common macros for the
32 type (i.e LDBL, DBL, or FLT).
33 LIT A function which appends the correct suffix to a literal.
34 TYPE_STR A macro which defines a stringitized name of the type.
35 FTOSTR This macro defines a function similar in type to strfromf
36 which converts a FLOAT to a string. */
37
38 /* Parameter handling is primitive in the moment:
39 --verbose=[0..3] for different levels of output:
40 0: only error count
41 1: basic report on failed tests (default)
42 2: full report on all tests
43 -v for full output (equals --verbose=3)
44 -u for generation of an ULPs file
45 */
46
47 /* "Philosophy":
48
49 This suite tests some aspects of the correct implementation of
50 mathematical functions in libm. Some simple, specific parameters
51 are tested for correctness but there's no exhaustive
52 testing. Handling of specific inputs (e.g. infinity, not-a-number)
53 is also tested. Correct handling of exceptions is checked
54 against. These implemented tests should check all cases that are
55 specified in ISO C99.
56
57 NaN values: The payload of NaNs is set in inputs for functions
58 where it is significant, and is examined in the outputs of some
59 functions.
60
61 Inline functions: Inlining functions should give an improvement in
62 speed - but not in precission. The inlined functions return
63 reasonable values for a reasonable range of input values. The
64 result is not necessarily correct for all values and exceptions are
65 not correctly raised in all cases. Problematic input and return
66 values are infinity, not-a-number and minus zero. This suite
67 therefore does not check these specific inputs and the exception
68 handling for inlined mathematical functions - just the "reasonable"
69 values are checked.
70
71 Beware: The tests might fail for any of the following reasons:
72 - Tests are wrong
73 - Functions are wrong
74 - Floating Point Unit not working properly
75 - Compiler has errors
76
77 With e.g. gcc 2.7.2.2 the test for cexp fails because of a compiler error.
78
79
80 To Do: All parameter should be numbers that can be represented as
81 exact floating point values. Currently some values cannot be
82 represented exactly and therefore the result is not the expected
83 result. For this we will use 36 digits so that numbers can be
84 represented exactly. */
85
86 #ifndef _GNU_SOURCE
87 # define _GNU_SOURCE
88 #endif
89
90 #include <complex.h>
91 #include <math.h>
92 #include <float.h>
93 #include <fenv.h>
94 #include <limits.h>
95
96 #include <errno.h>
97 #include <stdlib.h>
98 #include <stdint.h>
99 #include <stdio.h>
100 #include <string.h>
101 #include <argp.h>
102 #include <tininess.h>
103 #include <math-tests.h>
104 #include <math-tests-arch.h>
105 #include <nan-high-order-bit.h>
106
107 /* This header defines func_ulps, func_real_ulps and func_imag_ulps
108 arrays. */
109 #include "libm-test-ulps.h"
110
111 /* Allow platforms without all rounding modes to test properly,
112 assuming they provide an __FE_UNDEFINED in <bits/fenv.h> which
113 causes fesetround() to return failure. */
114 #ifndef FE_TONEAREST
115 # define FE_TONEAREST __FE_UNDEFINED
116 #endif
117 #ifndef FE_TOWARDZERO
118 # define FE_TOWARDZERO __FE_UNDEFINED
119 #endif
120 #ifndef FE_UPWARD
121 # define FE_UPWARD __FE_UNDEFINED
122 #endif
123 #ifndef FE_DOWNWARD
124 # define FE_DOWNWARD __FE_UNDEFINED
125 #endif
126
127 /* Possible exceptions */
128 #define NO_EXCEPTION 0x0
129 #define INVALID_EXCEPTION 0x1
130 #define DIVIDE_BY_ZERO_EXCEPTION 0x2
131 #define OVERFLOW_EXCEPTION 0x4
132 #define UNDERFLOW_EXCEPTION 0x8
133 #define INEXACT_EXCEPTION 0x10
134 /* The next flags signals that those exceptions are allowed but not required. */
135 #define INVALID_EXCEPTION_OK 0x20
136 #define DIVIDE_BY_ZERO_EXCEPTION_OK 0x40
137 #define OVERFLOW_EXCEPTION_OK 0x80
138 #define UNDERFLOW_EXCEPTION_OK 0x100
139 /* For "inexact" exceptions, the default is allowed but not required
140 unless INEXACT_EXCEPTION or NO_INEXACT_EXCEPTION is specified. */
141 #define NO_INEXACT_EXCEPTION 0x200
142 #define EXCEPTIONS_OK INVALID_EXCEPTION_OK+DIVIDE_BY_ZERO_EXCEPTION_OK
143 /* Some special test flags, passed together with exceptions. */
144 #define IGNORE_ZERO_INF_SIGN 0x400
145 #define TEST_NAN_SIGN 0x800
146 #define TEST_NAN_PAYLOAD 0x1000
147 #define NO_TEST_INLINE 0x2000
148 #define XFAIL_TEST 0x4000
149 /* Indicate errno settings required or disallowed. */
150 #define ERRNO_UNCHANGED 0x8000
151 #define ERRNO_EDOM 0x10000
152 #define ERRNO_ERANGE 0x20000
153 /* Flags generated by gen-libm-test.pl, not entered here manually. */
154 #define IGNORE_RESULT 0x40000
155 #define NON_FINITE 0x80000
156 #define TEST_SNAN 0x100000
157 #define NO_TEST_MATHVEC 0x200000
158
159 #define TEST_NAN_PAYLOAD_CANONICALIZE (SNAN_TESTS_PRESERVE_PAYLOAD \
160 ? TEST_NAN_PAYLOAD \
161 : 0)
162
163 #define __CONCATX(a,b) __CONCAT(a,b)
164
165 #define TYPE_MIN __CONCATX (PREFIX, _MIN)
166 #define TYPE_TRUE_MIN __CONCATX (PREFIX, _TRUE_MIN)
167 #define TYPE_MAX __CONCATX (PREFIX, _MAX)
168 #define MIN_EXP __CONCATX (PREFIX, _MIN_EXP)
169 #define MAX_EXP __CONCATX (PREFIX, _MAX_EXP)
170 #define MANT_DIG __CONCATX (PREFIX, _MANT_DIG)
171
172 /* Maximum character buffer to store a stringitized FLOAT value. */
173 #define FSTR_MAX (128)
174
175 #if TEST_INLINE
176 # define ULP_IDX __CONCATX (ULP_I_, PREFIX)
177 # define QTYPE_STR "i" TYPE_STR
178 #else
179 # define ULP_IDX __CONCATX (ULP_, PREFIX)
180 # define QTYPE_STR TYPE_STR
181 #endif
182
183 /* Format specific test macros. */
184 #define TEST_COND_binary32 (MANT_DIG == 24 \
185 && MIN_EXP == -125 \
186 && MAX_EXP == 128)
187
188 #define TEST_COND_binary64 (MANT_DIG == 53 \
189 && MIN_EXP == -1021 \
190 && MAX_EXP == 1024)
191
192 #define TEST_COND_binary128 (MANT_DIG == 113 \
193 && MIN_EXP == -16381 \
194 && MAX_EXP == 16384)
195
196 #define TEST_COND_ibm128 (MANT_DIG == 106)
197
198 #define TEST_COND_intel96 (MANT_DIG == 64 \
199 && MIN_EXP == -16381 \
200 && MAX_EXP == 16384)
201
202 #define TEST_COND_m68k96 (MANT_DIG == 64 \
203 && MIN_EXP == -16382 \
204 && MAX_EXP == 16384)
205
206 /* The condition ibm128-libgcc is used instead of ibm128 to mark tests
207 where in principle the glibc code is OK but the tests fail because
208 of limitations of the libgcc support for that format (e.g. GCC bug
209 59666, in non-default rounding modes). */
210 #define TEST_COND_ibm128_libgcc TEST_COND_ibm128
211
212 /* Mark a test as expected to fail for ibm128-libgcc. This is used
213 via XFAIL_ROUNDING_IBM128_LIBGCC, which gen-libm-test.pl transforms
214 appropriately for each rounding mode. */
215 #define XFAIL_IBM128_LIBGCC (TEST_COND_ibm128_libgcc ? XFAIL_TEST : 0)
216
217 /* Number of bits in NaN payload. */
218 #if TEST_COND_ibm128
219 # define PAYLOAD_DIG (DBL_MANT_DIG - 2)
220 #else
221 # define PAYLOAD_DIG (MANT_DIG - 2)
222 #endif
223
224 /* Values underflowing only for float. */
225 #if TEST_COND_binary32
226 # define UNDERFLOW_EXCEPTION_FLOAT UNDERFLOW_EXCEPTION
227 # define UNDERFLOW_EXCEPTION_OK_FLOAT UNDERFLOW_EXCEPTION_OK
228 #else
229 # define UNDERFLOW_EXCEPTION_FLOAT 0
230 # define UNDERFLOW_EXCEPTION_OK_FLOAT 0
231 #endif
232
233 /* Values underflowing only for double or types with a larger least
234 positive normal value. */
235 #if TEST_COND_binary32 || TEST_COND_binary64 || TEST_COND_ibm128
236 # define UNDERFLOW_EXCEPTION_DOUBLE UNDERFLOW_EXCEPTION
237 # define UNDERFLOW_EXCEPTION_OK_DOUBLE UNDERFLOW_EXCEPTION_OK
238 #else
239 # define UNDERFLOW_EXCEPTION_DOUBLE 0
240 # define UNDERFLOW_EXCEPTION_OK_DOUBLE 0
241 #endif
242
243 /* Values underflowing only for IBM long double or types with a larger least
244 positive normal value. */
245 #if TEST_COND_binary32 || TEST_COND_ibm128
246 # define UNDERFLOW_EXCEPTION_LDOUBLE_IBM UNDERFLOW_EXCEPTION
247 #else
248 # define UNDERFLOW_EXCEPTION_LDOUBLE_IBM 0
249 #endif
250
251 /* Values underflowing on architectures detecting tininess before
252 rounding, but not on those detecting tininess after rounding. */
253 #define UNDERFLOW_EXCEPTION_BEFORE_ROUNDING (TININESS_AFTER_ROUNDING \
254 ? 0 \
255 : UNDERFLOW_EXCEPTION)
256
257 #if LONG_MAX == 0x7fffffff
258 # define TEST_COND_long32 1
259 # define TEST_COND_long64 0
260 #else
261 # define TEST_COND_long32 0
262 # define TEST_COND_long64 1
263 #endif
264 #define TEST_COND_before_rounding (!TININESS_AFTER_ROUNDING)
265 #define TEST_COND_after_rounding TININESS_AFTER_ROUNDING
266
267 /* Various constants derived from pi. We must supply them precalculated for
268 accuracy. They are written as a series of postfix operations to keep
269 them concise yet somewhat readable. */
270
271 /* (pi * 3) / 4 */
272 #define lit_pi_3_m_4_d LIT (2.356194490192344928846982537459627163)
273 /* pi * 3 / (4 * ln(10)) */
274 #define lit_pi_3_m_4_ln10_m_d LIT (1.023282265381381010614337719073516828)
275 /* pi / (2 * ln(10)) */
276 #define lit_pi_2_ln10_m_d LIT (0.682188176920920673742891812715677885)
277 /* pi / (4 * ln(10)) */
278 #define lit_pi_4_ln10_m_d LIT (0.341094088460460336871445906357838943)
279 /* pi / ln(10) */
280 #define lit_pi_ln10_d LIT (1.364376353841841347485783625431355770)
281 /* pi / 2 */
282 #define lit_pi_2_d LITM (M_PI_2)
283 /* pi / 4 */
284 #define lit_pi_4_d LITM (M_PI_4)
285 /* pi */
286 #define lit_pi LITM (M_PI)
287
288 /* Other useful constants. */
289
290 /* e */
291 #define lit_e LITM (M_E)
292
293 #define ulps_file_name "ULPs" /* Name of the ULPs file. */
294 static FILE *ulps_file; /* File to document difference. */
295 static int output_ulps; /* Should ulps printed? */
296 static char *output_dir; /* Directory where generated files will be written. */
297
298 static int noErrors; /* number of errors */
299 static int noTests; /* number of tests (without testing exceptions) */
300 static int noExcTests; /* number of tests for exception flags */
301 static int noErrnoTests;/* number of tests for errno values */
302
303 static int verbose;
304 static int output_max_error; /* Should the maximal errors printed? */
305 static int output_points; /* Should the single function results printed? */
306 static int ignore_max_ulp; /* Should we ignore max_ulp? */
307
308 #define plus_zero LIT (0.0)
309 #define minus_zero LIT (-0.0)
310 #define plus_infty FUNC (__builtin_inf) ()
311 #define minus_infty -(FUNC (__builtin_inf) ())
312 #define qnan_value_pl(S) FUNC (__builtin_nan) (S)
313 #define qnan_value qnan_value_pl ("")
314 #define snan_value_pl(S) FUNC (__builtin_nans) (S)
315 #define snan_value snan_value_pl ("")
316 #define max_value TYPE_MAX
317 #define min_value TYPE_MIN
318 #define min_subnorm_value TYPE_TRUE_MIN
319
320 /* For nexttoward tests. */
321 #define snan_value_ld __builtin_nansl ("")
322
323 static FLOAT max_error, real_max_error, imag_max_error;
324
325 static FLOAT prev_max_error, prev_real_max_error, prev_imag_max_error;
326
327 static FLOAT max_valid_error;
328
329 /* Sufficient numbers of digits to represent any floating-point value
330 unambiguously (for any choice of the number of bits in the first
331 hex digit, in the case of TYPE_HEX_DIG). When used with printf
332 formats where the precision counts only digits after the point, 1
333 is subtracted from these values. */
334 #define TYPE_DECIMAL_DIG __CONCATX (PREFIX, _DECIMAL_DIG)
335 #define TYPE_HEX_DIG ((MANT_DIG + 6) / 4)
336
337 /* Converts VALUE (a floating-point number) to string and writes it to DEST.
338 PRECISION specifies the number of fractional digits that should be printed.
339 CONVERSION is the conversion specifier, such as in printf, e.g. 'f' or 'a'.
340 The output is prepended with an empty space if VALUE is non-negative. */
341 static void
342 fmt_ftostr (char *dest, size_t size, int precision, const char *conversion,
343 FLOAT value)
344 {
345 char format[64];
346 char *ptr_format;
347 int ret;
348
349 /* Generate the format string. */
350 ptr_format = stpcpy (format, "%.");
351 ret = sprintf (ptr_format, "%d", precision);
352 ptr_format += ret;
353 ptr_format = stpcpy (ptr_format, conversion);
354
355 /* Add a space to the beginning of the output string, if the floating-point
356 number is non-negative. This mimics the behavior of the space (' ') flag
357 in snprintf, which is not available on strfrom. */
358 if (! signbit (value))
359 {
360 *dest = ' ';
361 dest++;
362 size--;
363 }
364
365 /* Call the float to string conversion function, e.g.: strfromd. */
366 FTOSTR (dest, size, format, value);
367 }
368
369 /* Compare KEY (a string, with the name of a function) with ULP (a
370 pointer to a struct ulp_data structure), returning a value less
371 than, equal to or greater than zero for use in bsearch. */
372
373 static int
374 compare_ulp_data (const void *key, const void *ulp)
375 {
376 const char *keystr = key;
377 const struct ulp_data *ulpdat = ulp;
378 return strcmp (keystr, ulpdat->name);
379 }
380
381 /* Return the ulps for NAME in array DATA with NMEMB elements, or 0 if
382 no ulps listed. */
383
384 static FLOAT
385 find_ulps (const char *name, const struct ulp_data *data, size_t nmemb)
386 {
387 const struct ulp_data *entry = bsearch (name, data, nmemb, sizeof (*data),
388 compare_ulp_data);
389 if (entry == NULL)
390 return 0;
391 else
392 return entry->max_ulp[ULP_IDX];
393 }
394
395 static void
396 init_max_error (const char *name, int exact)
397 {
398 max_error = 0;
399 real_max_error = 0;
400 imag_max_error = 0;
401 prev_max_error = find_ulps (name, func_ulps,
402 sizeof (func_ulps) / sizeof (func_ulps[0]));
403 prev_real_max_error = find_ulps (name, func_real_ulps,
404 (sizeof (func_real_ulps)
405 / sizeof (func_real_ulps[0])));
406 prev_imag_max_error = find_ulps (name, func_imag_ulps,
407 (sizeof (func_imag_ulps)
408 / sizeof (func_imag_ulps[0])));
409 #if TEST_COND_ibm128
410 /* The documented accuracy of IBM long double division is 3ulp (see
411 libgcc/config/rs6000/ibm-ldouble-format), so do not require
412 better accuracy for libm functions that are exactly defined for
413 other formats. */
414 max_valid_error = exact ? 3 : 16;
415 #else
416 max_valid_error = exact ? 0 : 9;
417 #endif
418 prev_max_error = (prev_max_error <= max_valid_error
419 ? prev_max_error
420 : max_valid_error);
421 prev_real_max_error = (prev_real_max_error <= max_valid_error
422 ? prev_real_max_error
423 : max_valid_error);
424 prev_imag_max_error = (prev_imag_max_error <= max_valid_error
425 ? prev_imag_max_error
426 : max_valid_error);
427 feclearexcept (FE_ALL_EXCEPT);
428 errno = 0;
429 }
430
431 static void
432 set_max_error (FLOAT current, FLOAT *curr_max_error)
433 {
434 if (current > *curr_max_error && current <= max_valid_error)
435 *curr_max_error = current;
436 }
437
438
439 /* Print a FLOAT. */
440 static void
441 print_float (FLOAT f)
442 {
443 /* As printf doesn't differ between a sNaN and a qNaN, do this manually. */
444 if (issignaling (f))
445 printf ("sNaN\n");
446 else if (isnan (f))
447 printf ("qNaN\n");
448 else
449 {
450 char fstrn[FSTR_MAX], fstrx[FSTR_MAX];
451 fmt_ftostr (fstrn, FSTR_MAX, TYPE_DECIMAL_DIG - 1, "e", f);
452 fmt_ftostr (fstrx, FSTR_MAX, TYPE_HEX_DIG - 1, "a", f);
453 printf ("%s %s\n", fstrn, fstrx);
454 }
455 }
456
457 /* Should the message print to screen? This depends on the verbose flag,
458 and the test status. */
459 static int
460 print_screen (int ok)
461 {
462 if (output_points
463 && (verbose > 1
464 || (verbose == 1 && ok == 0)))
465 return 1;
466 return 0;
467 }
468
469
470 /* Should the message print to screen? This depends on the verbose flag,
471 and the test status. */
472 static int
473 print_screen_max_error (int ok)
474 {
475 if (output_max_error
476 && (verbose > 1
477 || ((verbose == 1) && (ok == 0))))
478 return 1;
479 return 0;
480 }
481
482 /* Update statistic counters. */
483 static void
484 update_stats (int ok)
485 {
486 ++noTests;
487 if (!ok)
488 ++noErrors;
489 }
490
491 static void
492 print_function_ulps (const char *function_name, FLOAT ulp)
493 {
494 if (output_ulps)
495 {
496 char ustrn[FSTR_MAX];
497 FTOSTR (ustrn, FSTR_MAX, "%.0f", FUNC (ceil) (ulp));
498 fprintf (ulps_file, "Function: \"%s\":\n", function_name);
499 fprintf (ulps_file, QTYPE_STR ": %s\n", ustrn);
500 }
501 }
502
503
504 static void
505 print_complex_function_ulps (const char *function_name, FLOAT real_ulp,
506 FLOAT imag_ulp)
507 {
508 if (output_ulps)
509 {
510 char fstrn[FSTR_MAX];
511 if (real_ulp != 0.0)
512 {
513 FTOSTR (fstrn, FSTR_MAX, "%.0f", FUNC (ceil) (real_ulp));
514 fprintf (ulps_file, "Function: Real part of \"%s\":\n", function_name);
515 fprintf (ulps_file, QTYPE_STR ": %s\n", fstrn);
516 }
517 if (imag_ulp != 0.0)
518 {
519 FTOSTR (fstrn, FSTR_MAX, "%.0f", FUNC (ceil) (imag_ulp));
520 fprintf (ulps_file, "Function: Imaginary part of \"%s\":\n", function_name);
521 fprintf (ulps_file, QTYPE_STR ": %s\n", fstrn);
522 }
523
524
525 }
526 }
527
528
529
530 /* Test if Floating-Point stack hasn't changed */
531 static void
532 fpstack_test (const char *test_name)
533 {
534 #if defined (__i386__) || defined (__x86_64__)
535 static int old_stack;
536 int sw;
537
538 asm ("fnstsw" : "=a" (sw));
539 sw >>= 11;
540 sw &= 7;
541
542 if (sw != old_stack)
543 {
544 printf ("FP-Stack wrong after test %s (%d, should be %d)\n",
545 test_name, sw, old_stack);
546 ++noErrors;
547 old_stack = sw;
548 }
549 #endif
550 }
551
552
553 static void
554 print_max_error (const char *func_name)
555 {
556 int ok = 0;
557
558 if (max_error == 0.0 || (max_error <= prev_max_error && !ignore_max_ulp))
559 {
560 ok = 1;
561 }
562
563 if (!ok)
564 print_function_ulps (func_name, max_error);
565
566
567 if (print_screen_max_error (ok))
568 {
569 char mestr[FSTR_MAX], pmestr[FSTR_MAX];
570 FTOSTR (mestr, FSTR_MAX, "%.0f", FUNC (ceil) (max_error));
571 FTOSTR (pmestr, FSTR_MAX, "%.0f", FUNC (ceil) (prev_max_error));
572 printf ("Maximal error of `%s'\n", func_name);
573 printf (" is : %s ulp\n", mestr);
574 printf (" accepted: %s ulp\n", pmestr);
575 }
576
577 update_stats (ok);
578 }
579
580
581 static void
582 print_complex_max_error (const char *func_name)
583 {
584 int real_ok = 0, imag_ok = 0, ok;
585
586 if (real_max_error == 0
587 || (real_max_error <= prev_real_max_error && !ignore_max_ulp))
588 {
589 real_ok = 1;
590 }
591
592 if (imag_max_error == 0
593 || (imag_max_error <= prev_imag_max_error && !ignore_max_ulp))
594 {
595 imag_ok = 1;
596 }
597
598 ok = real_ok && imag_ok;
599
600 if (!ok)
601 print_complex_function_ulps (func_name,
602 real_ok ? 0 : real_max_error,
603 imag_ok ? 0 : imag_max_error);
604
605 if (print_screen_max_error (ok))
606 {
607 char rmestr[FSTR_MAX], prmestr[FSTR_MAX];
608 char imestr[FSTR_MAX], pimestr[FSTR_MAX];
609 FTOSTR (rmestr, FSTR_MAX, "%.0f", FUNC (ceil) (real_max_error));
610 FTOSTR (prmestr, FSTR_MAX, "%.0f", FUNC (ceil) (prev_real_max_error));
611 FTOSTR (imestr, FSTR_MAX, "%.0f", FUNC (ceil) (imag_max_error));
612 FTOSTR (pimestr, FSTR_MAX, "%.0f", FUNC (ceil) (prev_imag_max_error));
613 printf ("Maximal error of real part of: %s\n", func_name);
614 printf (" is : %s ulp\n", rmestr);
615 printf (" accepted: %s ulp\n", prmestr);
616 printf ("Maximal error of imaginary part of: %s\n", func_name);
617 printf (" is : %s ulp\n", imestr);
618 printf (" accepted: %s ulp\n", pimestr);
619 }
620
621 update_stats (ok);
622 }
623
624
625 #if FE_ALL_EXCEPT
626 /* Test whether a given exception was raised. */
627 static void
628 test_single_exception (const char *test_name,
629 int exception,
630 int exc_flag,
631 int fe_flag,
632 const char *flag_name)
633 {
634 int ok = 1;
635 if (exception & exc_flag)
636 {
637 if (fetestexcept (fe_flag))
638 {
639 if (print_screen (1))
640 printf ("Pass: %s: Exception \"%s\" set\n", test_name, flag_name);
641 }
642 else
643 {
644 ok = 0;
645 if (print_screen (0))
646 printf ("Failure: %s: Exception \"%s\" not set\n",
647 test_name, flag_name);
648 }
649 }
650 else
651 {
652 if (fetestexcept (fe_flag))
653 {
654 ok = 0;
655 if (print_screen (0))
656 printf ("Failure: %s: Exception \"%s\" set\n",
657 test_name, flag_name);
658 }
659 else
660 {
661 if (print_screen (1))
662 printf ("%s: Exception \"%s\" not set\n", test_name,
663 flag_name);
664 }
665 }
666 if (!ok)
667 ++noErrors;
668 }
669 #endif
670
671 /* Test whether exceptions given by EXCEPTION are raised. Ignore thereby
672 allowed but not required exceptions.
673 */
674 static void
675 test_exceptions (const char *test_name, int exception)
676 {
677 if (TEST_EXCEPTIONS && EXCEPTION_TESTS (FLOAT))
678 {
679 ++noExcTests;
680 #ifdef FE_DIVBYZERO
681 if ((exception & DIVIDE_BY_ZERO_EXCEPTION_OK) == 0)
682 test_single_exception (test_name, exception,
683 DIVIDE_BY_ZERO_EXCEPTION, FE_DIVBYZERO,
684 "Divide by zero");
685 #endif
686 #ifdef FE_INVALID
687 if ((exception & INVALID_EXCEPTION_OK) == 0)
688 test_single_exception (test_name, exception,
689 INVALID_EXCEPTION, FE_INVALID,
690 "Invalid operation");
691 #endif
692 #ifdef FE_OVERFLOW
693 if ((exception & OVERFLOW_EXCEPTION_OK) == 0)
694 test_single_exception (test_name, exception, OVERFLOW_EXCEPTION,
695 FE_OVERFLOW, "Overflow");
696 #endif
697 /* Spurious "underflow" and "inexact" exceptions are always
698 allowed for IBM long double, in line with the underlying
699 arithmetic. */
700 #ifdef FE_UNDERFLOW
701 if ((exception & UNDERFLOW_EXCEPTION_OK) == 0
702 && !(TEST_COND_ibm128
703 && (exception & UNDERFLOW_EXCEPTION) == 0))
704 test_single_exception (test_name, exception, UNDERFLOW_EXCEPTION,
705 FE_UNDERFLOW, "Underflow");
706 #endif
707 #ifdef FE_INEXACT
708 if ((exception & (INEXACT_EXCEPTION | NO_INEXACT_EXCEPTION)) != 0
709 && !(TEST_COND_ibm128
710 && (exception & NO_INEXACT_EXCEPTION) != 0))
711 test_single_exception (test_name, exception, INEXACT_EXCEPTION,
712 FE_INEXACT, "Inexact");
713 #endif
714 }
715 feclearexcept (FE_ALL_EXCEPT);
716 }
717
718 /* Test whether errno for TEST_NAME, set to ERRNO_VALUE, has value
719 EXPECTED_VALUE (description EXPECTED_NAME). */
720 static void
721 test_single_errno (const char *test_name, int errno_value,
722 int expected_value, const char *expected_name)
723 {
724 if (errno_value == expected_value)
725 {
726 if (print_screen (1))
727 printf ("Pass: %s: errno set to %d (%s)\n", test_name, errno_value,
728 expected_name);
729 }
730 else
731 {
732 ++noErrors;
733 if (print_screen (0))
734 printf ("Failure: %s: errno set to %d, expected %d (%s)\n",
735 test_name, errno_value, expected_value, expected_name);
736 }
737 }
738
739 /* Test whether errno (value ERRNO_VALUE) has been for TEST_NAME set
740 as required by EXCEPTIONS. */
741 static void
742 test_errno (const char *test_name, int errno_value, int exceptions)
743 {
744 if (TEST_ERRNO)
745 {
746 ++noErrnoTests;
747 if (exceptions & ERRNO_UNCHANGED)
748 test_single_errno (test_name, errno_value, 0, "unchanged");
749 if (exceptions & ERRNO_EDOM)
750 test_single_errno (test_name, errno_value, EDOM, "EDOM");
751 if (exceptions & ERRNO_ERANGE)
752 test_single_errno (test_name, errno_value, ERANGE, "ERANGE");
753 }
754 }
755
756 /* Returns the number of ulps that GIVEN is away from EXPECTED. */
757 #define ULPDIFF(given, expected) \
758 (FUNC(fabs) ((given) - (expected)) / ulp (expected))
759
760 /* Returns the size of an ulp for VALUE. */
761 static FLOAT
762 ulp (FLOAT value)
763 {
764 FLOAT ulp;
765
766 switch (fpclassify (value))
767 {
768 case FP_ZERO:
769 /* We compute the distance to the next FP which is the same as the
770 value of the smallest subnormal number. Previously we used
771 2^-(MANT_DIG - 1) which is too large a value to be useful. Note that we
772 can't use ilogb(0), since that isn't a valid thing to do. As a point
773 of comparison Java's ulp returns the next normal value e.g.
774 2^(1 - MAX_EXP) for ulp(0), but that is not what we want for
775 glibc. */
776 /* Fall through... */
777 case FP_SUBNORMAL:
778 /* The next closest subnormal value is a constant distance away. */
779 ulp = FUNC(ldexp) (1.0, MIN_EXP - MANT_DIG);
780 break;
781
782 case FP_NORMAL:
783 ulp = FUNC(ldexp) (1.0, FUNC(ilogb) (value) - MANT_DIG + 1);
784 break;
785
786 default:
787 /* It should never happen. */
788 abort ();
789 break;
790 }
791 return ulp;
792 }
793
794 static void
795 check_float_internal (const char *test_name, FLOAT computed, FLOAT expected,
796 int exceptions,
797 FLOAT *curr_max_error, FLOAT max_ulp)
798 {
799 int ok = 0;
800 int print_diff = 0;
801 FLOAT diff = 0;
802 FLOAT ulps = 0;
803 int errno_value = errno;
804
805 test_exceptions (test_name, exceptions);
806 test_errno (test_name, errno_value, exceptions);
807 if (exceptions & IGNORE_RESULT)
808 goto out;
809 if (issignaling (computed) && issignaling (expected))
810 {
811 if ((exceptions & TEST_NAN_SIGN) != 0
812 && signbit (computed) != signbit (expected))
813 {
814 ok = 0;
815 printf ("signaling NaN has wrong sign.\n");
816 }
817 else if ((exceptions & TEST_NAN_PAYLOAD) != 0
818 && (FUNC (getpayload) (&computed)
819 != FUNC (getpayload) (&expected)))
820 {
821 ok = 0;
822 printf ("signaling NaN has wrong payload.\n");
823 }
824 else
825 ok = 1;
826 }
827 else if (issignaling (computed) || issignaling (expected))
828 ok = 0;
829 else if (isnan (computed) && isnan (expected))
830 {
831 if ((exceptions & TEST_NAN_SIGN) != 0
832 && signbit (computed) != signbit (expected))
833 {
834 ok = 0;
835 printf ("quiet NaN has wrong sign.\n");
836 }
837 else if ((exceptions & TEST_NAN_PAYLOAD) != 0
838 && (FUNC (getpayload) (&computed)
839 != FUNC (getpayload) (&expected)))
840 {
841 ok = 0;
842 printf ("quiet NaN has wrong payload.\n");
843 }
844 else
845 ok = 1;
846 }
847 else if (isinf (computed) && isinf (expected))
848 {
849 /* Test for sign of infinities. */
850 if ((exceptions & IGNORE_ZERO_INF_SIGN) == 0
851 && signbit (computed) != signbit (expected))
852 {
853 ok = 0;
854 printf ("infinity has wrong sign.\n");
855 }
856 else
857 ok = 1;
858 }
859 /* Don't calculate ULPs for infinities or any kind of NaNs. */
860 else if (isinf (computed) || isnan (computed)
861 || isinf (expected) || isnan (expected))
862 ok = 0;
863 else
864 {
865 diff = FUNC(fabs) (computed - expected);
866 ulps = ULPDIFF (computed, expected);
867 set_max_error (ulps, curr_max_error);
868 print_diff = 1;
869 if ((exceptions & IGNORE_ZERO_INF_SIGN) == 0
870 && computed == 0.0 && expected == 0.0
871 && signbit(computed) != signbit (expected))
872 ok = 0;
873 else if (ulps <= max_ulp && !ignore_max_ulp)
874 ok = 1;
875 else
876 ok = 0;
877 }
878 if (print_screen (ok))
879 {
880 if (!ok)
881 printf ("Failure: ");
882 printf ("Test: %s\n", test_name);
883 printf ("Result:\n");
884 printf (" is: ");
885 print_float (computed);
886 printf (" should be: ");
887 print_float (expected);
888 if (print_diff)
889 {
890 char dstrn[FSTR_MAX], dstrx[FSTR_MAX];
891 char ustrn[FSTR_MAX], mustrn[FSTR_MAX];
892 fmt_ftostr (dstrn, FSTR_MAX, TYPE_DECIMAL_DIG - 1, "e", diff);
893 fmt_ftostr (dstrx, FSTR_MAX, TYPE_HEX_DIG - 1, "a", diff);
894 fmt_ftostr (ustrn, FSTR_MAX, 4, "f", ulps);
895 fmt_ftostr (mustrn, FSTR_MAX, 4, "f", max_ulp);
896 printf (" difference: %s %s\n", dstrn, dstrx);
897 printf (" ulp : %s\n", ustrn);
898 printf (" max.ulp : %s\n", mustrn);
899 }
900 }
901 update_stats (ok);
902
903 out:
904 fpstack_test (test_name);
905 errno = 0;
906 }
907
908
909 static void
910 check_float (const char *test_name, FLOAT computed, FLOAT expected,
911 int exceptions)
912 {
913 check_float_internal (test_name, computed, expected,
914 exceptions, &max_error, prev_max_error);
915 }
916
917
918 static void
919 check_complex (const char *test_name, __complex__ FLOAT computed,
920 __complex__ FLOAT expected,
921 int exception)
922 {
923 FLOAT part_comp, part_exp;
924 char *str;
925
926 if (asprintf (&str, "Real part of: %s", test_name) == -1)
927 abort ();
928
929 part_comp = __real__ computed;
930 part_exp = __real__ expected;
931
932 check_float_internal (str, part_comp, part_exp,
933 exception, &real_max_error, prev_real_max_error);
934 free (str);
935
936 if (asprintf (&str, "Imaginary part of: %s", test_name) == -1)
937 abort ();
938
939 part_comp = __imag__ computed;
940 part_exp = __imag__ expected;
941
942 /* Don't check again for exceptions or errno, just pass through the
943 other relevant flags. */
944 check_float_internal (str, part_comp, part_exp,
945 exception & (IGNORE_ZERO_INF_SIGN
946 | TEST_NAN_SIGN
947 | IGNORE_RESULT),
948 &imag_max_error, prev_imag_max_error);
949 free (str);
950 }
951
952
953 /* Check that computed and expected values are equal (int values). */
954 static void
955 check_int (const char *test_name, int computed, int expected,
956 int exceptions)
957 {
958 int ok = 0;
959 int errno_value = errno;
960
961 test_exceptions (test_name, exceptions);
962 test_errno (test_name, errno_value, exceptions);
963 if (exceptions & IGNORE_RESULT)
964 goto out;
965 noTests++;
966 if (computed == expected)
967 ok = 1;
968
969 if (print_screen (ok))
970 {
971 if (!ok)
972 printf ("Failure: ");
973 printf ("Test: %s\n", test_name);
974 printf ("Result:\n");
975 printf (" is: %d\n", computed);
976 printf (" should be: %d\n", expected);
977 }
978
979 update_stats (ok);
980 out:
981 fpstack_test (test_name);
982 errno = 0;
983 }
984
985
986 /* Check that computed and expected values are equal (long int values). */
987 static void
988 check_long (const char *test_name, long int computed, long int expected,
989 int exceptions)
990 {
991 int ok = 0;
992 int errno_value = errno;
993
994 test_exceptions (test_name, exceptions);
995 test_errno (test_name, errno_value, exceptions);
996 if (exceptions & IGNORE_RESULT)
997 goto out;
998 noTests++;
999 if (computed == expected)
1000 ok = 1;
1001
1002 if (print_screen (ok))
1003 {
1004 if (!ok)
1005 printf ("Failure: ");
1006 printf ("Test: %s\n", test_name);
1007 printf ("Result:\n");
1008 printf (" is: %ld\n", computed);
1009 printf (" should be: %ld\n", expected);
1010 }
1011
1012 update_stats (ok);
1013 out:
1014 fpstack_test (test_name);
1015 errno = 0;
1016 }
1017
1018
1019 /* Check that computed value is true/false. */
1020 static void
1021 check_bool (const char *test_name, int computed, int expected,
1022 int exceptions)
1023 {
1024 int ok = 0;
1025 int errno_value = errno;
1026
1027 test_exceptions (test_name, exceptions);
1028 test_errno (test_name, errno_value, exceptions);
1029 if (exceptions & IGNORE_RESULT)
1030 goto out;
1031 noTests++;
1032 if ((computed == 0) == (expected == 0))
1033 ok = 1;
1034
1035 if (print_screen (ok))
1036 {
1037 if (!ok)
1038 printf ("Failure: ");
1039 printf ("Test: %s\n", test_name);
1040 printf ("Result:\n");
1041 printf (" is: %d\n", computed);
1042 printf (" should be: %d\n", expected);
1043 }
1044
1045 update_stats (ok);
1046 out:
1047 fpstack_test (test_name);
1048 errno = 0;
1049 }
1050
1051
1052 /* check that computed and expected values are equal (long int values) */
1053 static void
1054 check_longlong (const char *test_name, long long int computed,
1055 long long int expected,
1056 int exceptions)
1057 {
1058 int ok = 0;
1059 int errno_value = errno;
1060
1061 test_exceptions (test_name, exceptions);
1062 test_errno (test_name, errno_value, exceptions);
1063 if (exceptions & IGNORE_RESULT)
1064 goto out;
1065 noTests++;
1066 if (computed == expected)
1067 ok = 1;
1068
1069 if (print_screen (ok))
1070 {
1071 if (!ok)
1072 printf ("Failure:");
1073 printf ("Test: %s\n", test_name);
1074 printf ("Result:\n");
1075 printf (" is: %lld\n", computed);
1076 printf (" should be: %lld\n", expected);
1077 }
1078
1079 update_stats (ok);
1080 out:
1081 fpstack_test (test_name);
1082 errno = 0;
1083 }
1084
1085
1086 /* Check that computed and expected values are equal (intmax_t values). */
1087 static void
1088 check_intmax_t (const char *test_name, intmax_t computed,
1089 intmax_t expected, int exceptions)
1090 {
1091 int ok = 0;
1092 int errno_value = errno;
1093
1094 test_exceptions (test_name, exceptions);
1095 test_errno (test_name, errno_value, exceptions);
1096 if (exceptions & IGNORE_RESULT)
1097 goto out;
1098 noTests++;
1099 if (computed == expected)
1100 ok = 1;
1101
1102 if (print_screen (ok))
1103 {
1104 if (!ok)
1105 printf ("Failure:");
1106 printf ("Test: %s\n", test_name);
1107 printf ("Result:\n");
1108 printf (" is: %jd\n", computed);
1109 printf (" should be: %jd\n", expected);
1110 }
1111
1112 update_stats (ok);
1113 out:
1114 fpstack_test (test_name);
1115 errno = 0;
1116 }
1117
1118
1119 /* Check that computed and expected values are equal (uintmax_t values). */
1120 static void
1121 check_uintmax_t (const char *test_name, uintmax_t computed,
1122 uintmax_t expected, int exceptions)
1123 {
1124 int ok = 0;
1125 int errno_value = errno;
1126
1127 test_exceptions (test_name, exceptions);
1128 test_errno (test_name, errno_value, exceptions);
1129 if (exceptions & IGNORE_RESULT)
1130 goto out;
1131 noTests++;
1132 if (computed == expected)
1133 ok = 1;
1134
1135 if (print_screen (ok))
1136 {
1137 if (!ok)
1138 printf ("Failure:");
1139 printf ("Test: %s\n", test_name);
1140 printf ("Result:\n");
1141 printf (" is: %ju\n", computed);
1142 printf (" should be: %ju\n", expected);
1143 }
1144
1145 update_stats (ok);
1146 out:
1147 fpstack_test (test_name);
1148 errno = 0;
1149 }
1150
1151 /* Return whether a test with flags EXCEPTIONS should be run. */
1152 static int
1153 enable_test (int exceptions)
1154 {
1155 if (exceptions & XFAIL_TEST)
1156 return 0;
1157 if (TEST_INLINE && (exceptions & NO_TEST_INLINE))
1158 return 0;
1159 if (TEST_FINITE && (exceptions & NON_FINITE) != 0)
1160 return 0;
1161 if (!SNAN_TESTS (FLOAT) && (exceptions & TEST_SNAN) != 0)
1162 return 0;
1163 if (TEST_MATHVEC && (exceptions & NO_TEST_MATHVEC) != 0)
1164 return 0;
1165
1166 return 1;
1167 }
1168
1169 /* Structures for each kind of test. */
1170 /* Used for both RUN_TEST_LOOP_f_f and RUN_TEST_LOOP_fp_f. */
1171 struct test_f_f_data
1172 {
1173 const char *arg_str;
1174 FLOAT arg;
1175 struct
1176 {
1177 FLOAT expected;
1178 int exceptions;
1179 } rd, rn, rz, ru;
1180 };
1181 struct test_ff_f_data
1182 {
1183 const char *arg_str;
1184 FLOAT arg1, arg2;
1185 struct
1186 {
1187 FLOAT expected;
1188 int exceptions;
1189 } rd, rn, rz, ru;
1190 };
1191 /* Strictly speaking, a j type argument is one gen-libm-test.pl will not
1192 attempt to muck with. For now, it is only used to prevent it from
1193 mucking up an explicitly long double argument. */
1194 struct test_fj_f_data
1195 {
1196 const char *arg_str;
1197 FLOAT arg1;
1198 long double arg2;
1199 struct
1200 {
1201 FLOAT expected;
1202 int exceptions;
1203 } rd, rn, rz, ru;
1204 };
1205 struct test_fi_f_data
1206 {
1207 const char *arg_str;
1208 FLOAT arg1;
1209 int arg2;
1210 struct
1211 {
1212 FLOAT expected;
1213 int exceptions;
1214 } rd, rn, rz, ru;
1215 };
1216 struct test_fl_f_data
1217 {
1218 const char *arg_str;
1219 FLOAT arg1;
1220 long int arg2;
1221 struct
1222 {
1223 FLOAT expected;
1224 int exceptions;
1225 } rd, rn, rz, ru;
1226 };
1227 struct test_if_f_data
1228 {
1229 const char *arg_str;
1230 int arg1;
1231 FLOAT arg2;
1232 struct
1233 {
1234 FLOAT expected;
1235 int exceptions;
1236 } rd, rn, rz, ru;
1237 };
1238 struct test_fff_f_data
1239 {
1240 const char *arg_str;
1241 FLOAT arg1, arg2, arg3;
1242 struct
1243 {
1244 FLOAT expected;
1245 int exceptions;
1246 } rd, rn, rz, ru;
1247 };
1248 struct test_fiu_M_data
1249 {
1250 const char *arg_str;
1251 FLOAT arg1;
1252 int arg2;
1253 unsigned int arg3;
1254 struct
1255 {
1256 intmax_t expected;
1257 int exceptions;
1258 } rd, rn, rz, ru;
1259 };
1260 struct test_fiu_U_data
1261 {
1262 const char *arg_str;
1263 FLOAT arg1;
1264 int arg2;
1265 unsigned int arg3;
1266 struct
1267 {
1268 uintmax_t expected;
1269 int exceptions;
1270 } rd, rn, rz, ru;
1271 };
1272 struct test_c_f_data
1273 {
1274 const char *arg_str;
1275 FLOAT argr, argc;
1276 struct
1277 {
1278 FLOAT expected;
1279 int exceptions;
1280 } rd, rn, rz, ru;
1281 };
1282 /* Used for both RUN_TEST_LOOP_f_f1 and RUN_TEST_LOOP_fI_f1. */
1283 struct test_f_f1_data
1284 {
1285 const char *arg_str;
1286 FLOAT arg;
1287 struct
1288 {
1289 FLOAT expected;
1290 int exceptions;
1291 int extra_test;
1292 int extra_expected;
1293 } rd, rn, rz, ru;
1294 };
1295 struct test_fF_f1_data
1296 {
1297 const char *arg_str;
1298 FLOAT arg;
1299 struct
1300 {
1301 FLOAT expected;
1302 int exceptions;
1303 int extra_test;
1304 FLOAT extra_expected;
1305 } rd, rn, rz, ru;
1306 };
1307 struct test_ffI_f1_data
1308 {
1309 const char *arg_str;
1310 FLOAT arg1, arg2;
1311 struct
1312 {
1313 FLOAT expected;
1314 int exceptions;
1315 int extra_test;
1316 int extra_expected;
1317 } rd, rn, rz, ru;
1318 };
1319 struct test_c_c_data
1320 {
1321 const char *arg_str;
1322 FLOAT argr, argc;
1323 struct
1324 {
1325 FLOAT expr, expc;
1326 int exceptions;
1327 } rd, rn, rz, ru;
1328 };
1329 struct test_cc_c_data
1330 {
1331 const char *arg_str;
1332 FLOAT arg1r, arg1c, arg2r, arg2c;
1333 struct
1334 {
1335 FLOAT expr, expc;
1336 int exceptions;
1337 } rd, rn, rz, ru;
1338 };
1339 /* Used for all of RUN_TEST_LOOP_f_i, RUN_TEST_LOOP_f_i_tg,
1340 RUN_TEST_LOOP_f_b and RUN_TEST_LOOP_f_b_tg. */
1341 struct test_f_i_data
1342 {
1343 const char *arg_str;
1344 FLOAT arg;
1345 struct
1346 {
1347 int expected;
1348 int exceptions;
1349 } rd, rn, rz, ru;
1350 };
1351 /* Used for both RUN_TEST_LOOP_ff_b and RUN_TEST_LOOP_ff_i_tg. */
1352 struct test_ff_i_data
1353 {
1354 const char *arg_str;
1355 FLOAT arg1, arg2;
1356 struct
1357 {
1358 int expected;
1359 int exceptions;
1360 } rd, rn, rz, ru;
1361 };
1362 struct test_f_l_data
1363 {
1364 const char *arg_str;
1365 FLOAT arg;
1366 struct
1367 {
1368 long int expected;
1369 int exceptions;
1370 } rd, rn, rz, ru;
1371 };
1372 struct test_f_L_data
1373 {
1374 const char *arg_str;
1375 FLOAT arg;
1376 struct
1377 {
1378 long long int expected;
1379 int exceptions;
1380 } rd, rn, rz, ru;
1381 };
1382 struct test_fFF_11_data
1383 {
1384 const char *arg_str;
1385 FLOAT arg;
1386 struct
1387 {
1388 int exceptions;
1389 int extra1_test;
1390 FLOAT extra1_expected;
1391 int extra2_test;
1392 FLOAT extra2_expected;
1393 } rd, rn, rz, ru;
1394 };
1395 /* Used for both RUN_TEST_LOOP_Ff_b1 and RUN_TEST_LOOP_Ffp_b1. */
1396 struct test_Ff_b1_data
1397 {
1398 const char *arg_str;
1399 FLOAT arg;
1400 struct
1401 {
1402 int expected;
1403 int exceptions;
1404 int extra_test;
1405 FLOAT extra_expected;
1406 } rd, rn, rz, ru;
1407 };
1408
1409 /* Set the rounding mode, or restore the saved value. */
1410 #define IF_ROUND_INIT_ /* Empty. */
1411 #define IF_ROUND_INIT_FE_DOWNWARD \
1412 int save_round_mode = fegetround (); \
1413 if (ROUNDING_TESTS (FLOAT, FE_DOWNWARD) \
1414 && fesetround (FE_DOWNWARD) == 0)
1415 #define IF_ROUND_INIT_FE_TONEAREST \
1416 int save_round_mode = fegetround (); \
1417 if (ROUNDING_TESTS (FLOAT, FE_TONEAREST) \
1418 && fesetround (FE_TONEAREST) == 0)
1419 #define IF_ROUND_INIT_FE_TOWARDZERO \
1420 int save_round_mode = fegetround (); \
1421 if (ROUNDING_TESTS (FLOAT, FE_TOWARDZERO) \
1422 && fesetround (FE_TOWARDZERO) == 0)
1423 #define IF_ROUND_INIT_FE_UPWARD \
1424 int save_round_mode = fegetround (); \
1425 if (ROUNDING_TESTS (FLOAT, FE_UPWARD) \
1426 && fesetround (FE_UPWARD) == 0)
1427 #define ROUND_RESTORE_ /* Empty. */
1428 #define ROUND_RESTORE_FE_DOWNWARD \
1429 fesetround (save_round_mode)
1430 #define ROUND_RESTORE_FE_TONEAREST \
1431 fesetround (save_round_mode)
1432 #define ROUND_RESTORE_FE_TOWARDZERO \
1433 fesetround (save_round_mode)
1434 #define ROUND_RESTORE_FE_UPWARD \
1435 fesetround (save_round_mode)
1436
1437 /* Field name to use for a given rounding mode. */
1438 #define RM_ rn
1439 #define RM_FE_DOWNWARD rd
1440 #define RM_FE_TONEAREST rn
1441 #define RM_FE_TOWARDZERO rz
1442 #define RM_FE_UPWARD ru
1443
1444 /* Common setup for an individual test. */
1445 #define COMMON_TEST_SETUP(ARG_STR) \
1446 char *test_name; \
1447 if (asprintf (&test_name, "%s (%s)", this_func, (ARG_STR)) == -1) \
1448 abort ()
1449
1450 /* Setup for a test with an extra output. */
1451 #define EXTRA_OUTPUT_TEST_SETUP(ARG_STR, N) \
1452 char *extra##N##_name; \
1453 if (asprintf (&extra##N##_name, "%s (%s) extra output " #N, \
1454 this_func, (ARG_STR)) == -1) \
1455 abort ()
1456
1457 /* Common cleanup after an individual test. */
1458 #define COMMON_TEST_CLEANUP \
1459 free (test_name)
1460
1461 /* Cleanup for a test with an extra output. */
1462 #define EXTRA_OUTPUT_TEST_CLEANUP(N) \
1463 free (extra##N##_name)
1464
1465 /* Run an individual test, including any required setup and checking
1466 of results, or loop over all tests in an array. */
1467 #define RUN_TEST_f_f(ARG_STR, FUNC_NAME, ARG, EXPECTED, \
1468 EXCEPTIONS) \
1469 do \
1470 if (enable_test (EXCEPTIONS)) \
1471 { \
1472 COMMON_TEST_SETUP (ARG_STR); \
1473 check_float (test_name, FUNC_TEST (FUNC_NAME) (ARG), \
1474 EXPECTED, EXCEPTIONS); \
1475 COMMON_TEST_CLEANUP; \
1476 } \
1477 while (0)
1478 #define RUN_TEST_LOOP_f_f(FUNC_NAME, ARRAY, ROUNDING_MODE) \
1479 IF_ROUND_INIT_ ## ROUNDING_MODE \
1480 for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++) \
1481 RUN_TEST_f_f ((ARRAY)[i].arg_str, FUNC_NAME, (ARRAY)[i].arg, \
1482 (ARRAY)[i].RM_##ROUNDING_MODE.expected, \
1483 (ARRAY)[i].RM_##ROUNDING_MODE.exceptions); \
1484 ROUND_RESTORE_ ## ROUNDING_MODE
1485 #define RUN_TEST_fp_f(ARG_STR, FUNC_NAME, ARG, EXPECTED, \
1486 EXCEPTIONS) \
1487 do \
1488 if (enable_test (EXCEPTIONS)) \
1489 { \
1490 COMMON_TEST_SETUP (ARG_STR); \
1491 check_float (test_name, FUNC_TEST (FUNC_NAME) (&(ARG)), \
1492 EXPECTED, EXCEPTIONS); \
1493 COMMON_TEST_CLEANUP; \
1494 } \
1495 while (0)
1496 #define RUN_TEST_LOOP_fp_f(FUNC_NAME, ARRAY, ROUNDING_MODE) \
1497 IF_ROUND_INIT_ ## ROUNDING_MODE \
1498 for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++) \
1499 RUN_TEST_fp_f ((ARRAY)[i].arg_str, FUNC_NAME, (ARRAY)[i].arg, \
1500 (ARRAY)[i].RM_##ROUNDING_MODE.expected, \
1501 (ARRAY)[i].RM_##ROUNDING_MODE.exceptions); \
1502 ROUND_RESTORE_ ## ROUNDING_MODE
1503 #define RUN_TEST_2_f(ARG_STR, FUNC_NAME, ARG1, ARG2, EXPECTED, \
1504 EXCEPTIONS) \
1505 do \
1506 if (enable_test (EXCEPTIONS)) \
1507 { \
1508 COMMON_TEST_SETUP (ARG_STR); \
1509 check_float (test_name, FUNC_TEST (FUNC_NAME) (ARG1, ARG2), \
1510 EXPECTED, EXCEPTIONS); \
1511 COMMON_TEST_CLEANUP; \
1512 } \
1513 while (0)
1514 #define RUN_TEST_LOOP_2_f(FUNC_NAME, ARRAY, ROUNDING_MODE) \
1515 IF_ROUND_INIT_ ## ROUNDING_MODE \
1516 for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++) \
1517 RUN_TEST_2_f ((ARRAY)[i].arg_str, FUNC_NAME, (ARRAY)[i].arg1, \
1518 (ARRAY)[i].arg2, \
1519 (ARRAY)[i].RM_##ROUNDING_MODE.expected, \
1520 (ARRAY)[i].RM_##ROUNDING_MODE.exceptions); \
1521 ROUND_RESTORE_ ## ROUNDING_MODE
1522 #define RUN_TEST_ff_f RUN_TEST_2_f
1523 #define RUN_TEST_LOOP_ff_f RUN_TEST_LOOP_2_f
1524 #define RUN_TEST_LOOP_fj_f RUN_TEST_LOOP_2_f
1525 #define RUN_TEST_fi_f RUN_TEST_2_f
1526 #define RUN_TEST_LOOP_fi_f RUN_TEST_LOOP_2_f
1527 #define RUN_TEST_fl_f RUN_TEST_2_f
1528 #define RUN_TEST_LOOP_fl_f RUN_TEST_LOOP_2_f
1529 #define RUN_TEST_if_f RUN_TEST_2_f
1530 #define RUN_TEST_LOOP_if_f RUN_TEST_LOOP_2_f
1531 #define RUN_TEST_fff_f(ARG_STR, FUNC_NAME, ARG1, ARG2, ARG3, \
1532 EXPECTED, EXCEPTIONS) \
1533 do \
1534 if (enable_test (EXCEPTIONS)) \
1535 { \
1536 COMMON_TEST_SETUP (ARG_STR); \
1537 check_float (test_name, FUNC_TEST (FUNC_NAME) (ARG1, ARG2, ARG3), \
1538 EXPECTED, EXCEPTIONS); \
1539 COMMON_TEST_CLEANUP; \
1540 } \
1541 while (0)
1542 #define RUN_TEST_LOOP_fff_f(FUNC_NAME, ARRAY, ROUNDING_MODE) \
1543 IF_ROUND_INIT_ ## ROUNDING_MODE \
1544 for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++) \
1545 RUN_TEST_fff_f ((ARRAY)[i].arg_str, FUNC_NAME, (ARRAY)[i].arg1, \
1546 (ARRAY)[i].arg2, (ARRAY)[i].arg3, \
1547 (ARRAY)[i].RM_##ROUNDING_MODE.expected, \
1548 (ARRAY)[i].RM_##ROUNDING_MODE.exceptions); \
1549 ROUND_RESTORE_ ## ROUNDING_MODE
1550 #define RUN_TEST_fiu_M(ARG_STR, FUNC_NAME, ARG1, ARG2, ARG3, \
1551 EXPECTED, EXCEPTIONS) \
1552 do \
1553 if (enable_test (EXCEPTIONS)) \
1554 { \
1555 COMMON_TEST_SETUP (ARG_STR); \
1556 check_intmax_t (test_name, \
1557 FUNC_TEST (FUNC_NAME) (ARG1, ARG2, ARG3), \
1558 EXPECTED, EXCEPTIONS); \
1559 COMMON_TEST_CLEANUP; \
1560 } \
1561 while (0)
1562 #define RUN_TEST_LOOP_fiu_M(FUNC_NAME, ARRAY, ROUNDING_MODE) \
1563 IF_ROUND_INIT_ ## ROUNDING_MODE \
1564 for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++) \
1565 RUN_TEST_fiu_M ((ARRAY)[i].arg_str, FUNC_NAME, (ARRAY)[i].arg1, \
1566 (ARRAY)[i].arg2, (ARRAY)[i].arg3, \
1567 (ARRAY)[i].RM_##ROUNDING_MODE.expected, \
1568 (ARRAY)[i].RM_##ROUNDING_MODE.exceptions); \
1569 ROUND_RESTORE_ ## ROUNDING_MODE
1570 #define RUN_TEST_fiu_U(ARG_STR, FUNC_NAME, ARG1, ARG2, ARG3, \
1571 EXPECTED, EXCEPTIONS) \
1572 do \
1573 if (enable_test (EXCEPTIONS)) \
1574 { \
1575 COMMON_TEST_SETUP (ARG_STR); \
1576 check_uintmax_t (test_name, \
1577 FUNC_TEST (FUNC_NAME) (ARG1, ARG2, ARG3), \
1578 EXPECTED, EXCEPTIONS); \
1579 COMMON_TEST_CLEANUP; \
1580 } \
1581 while (0)
1582 #define RUN_TEST_LOOP_fiu_U(FUNC_NAME, ARRAY, ROUNDING_MODE) \
1583 IF_ROUND_INIT_ ## ROUNDING_MODE \
1584 for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++) \
1585 RUN_TEST_fiu_U ((ARRAY)[i].arg_str, FUNC_NAME, (ARRAY)[i].arg1, \
1586 (ARRAY)[i].arg2, (ARRAY)[i].arg3, \
1587 (ARRAY)[i].RM_##ROUNDING_MODE.expected, \
1588 (ARRAY)[i].RM_##ROUNDING_MODE.exceptions); \
1589 ROUND_RESTORE_ ## ROUNDING_MODE
1590 #define RUN_TEST_c_f(ARG_STR, FUNC_NAME, ARG1, ARG2, EXPECTED, \
1591 EXCEPTIONS) \
1592 do \
1593 if (enable_test (EXCEPTIONS)) \
1594 { \
1595 COMMON_TEST_SETUP (ARG_STR); \
1596 check_float (test_name, \
1597 FUNC_TEST (FUNC_NAME) (BUILD_COMPLEX (ARG1, ARG2)),\
1598 EXPECTED, EXCEPTIONS); \
1599 COMMON_TEST_CLEANUP; \
1600 } \
1601 while (0)
1602 #define RUN_TEST_LOOP_c_f(FUNC_NAME, ARRAY, ROUNDING_MODE) \
1603 IF_ROUND_INIT_ ## ROUNDING_MODE \
1604 for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++) \
1605 RUN_TEST_c_f ((ARRAY)[i].arg_str, FUNC_NAME, (ARRAY)[i].argr, \
1606 (ARRAY)[i].argc, \
1607 (ARRAY)[i].RM_##ROUNDING_MODE.expected, \
1608 (ARRAY)[i].RM_##ROUNDING_MODE.exceptions); \
1609 ROUND_RESTORE_ ## ROUNDING_MODE
1610 #define RUN_TEST_f_f1(ARG_STR, FUNC_NAME, ARG, EXPECTED, \
1611 EXCEPTIONS, EXTRA_VAR, EXTRA_TEST, \
1612 EXTRA_EXPECTED) \
1613 do \
1614 if (enable_test (EXCEPTIONS)) \
1615 { \
1616 COMMON_TEST_SETUP (ARG_STR); \
1617 (EXTRA_VAR) = (EXTRA_EXPECTED) == 0 ? 1 : 0; \
1618 check_float (test_name, FUNC_TEST (FUNC_NAME) (ARG), EXPECTED, \
1619 EXCEPTIONS); \
1620 EXTRA_OUTPUT_TEST_SETUP (ARG_STR, 1); \
1621 if (EXTRA_TEST) \
1622 check_int (extra1_name, EXTRA_VAR, EXTRA_EXPECTED, 0); \
1623 EXTRA_OUTPUT_TEST_CLEANUP (1); \
1624 COMMON_TEST_CLEANUP; \
1625 } \
1626 while (0)
1627 #define RUN_TEST_LOOP_f_f1(FUNC_NAME, ARRAY, ROUNDING_MODE, EXTRA_VAR) \
1628 IF_ROUND_INIT_ ## ROUNDING_MODE \
1629 for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++) \
1630 RUN_TEST_f_f1 ((ARRAY)[i].arg_str, FUNC_NAME, (ARRAY)[i].arg, \
1631 (ARRAY)[i].RM_##ROUNDING_MODE.expected, \
1632 (ARRAY)[i].RM_##ROUNDING_MODE.exceptions, \
1633 EXTRA_VAR, \
1634 (ARRAY)[i].RM_##ROUNDING_MODE.extra_test, \
1635 (ARRAY)[i].RM_##ROUNDING_MODE.extra_expected); \
1636 ROUND_RESTORE_ ## ROUNDING_MODE
1637 #define RUN_TEST_fF_f1(ARG_STR, FUNC_NAME, ARG, EXPECTED, \
1638 EXCEPTIONS, EXTRA_VAR, EXTRA_TEST, \
1639 EXTRA_EXPECTED) \
1640 do \
1641 if (enable_test (EXCEPTIONS)) \
1642 { \
1643 COMMON_TEST_SETUP (ARG_STR); \
1644 (EXTRA_VAR) = (EXTRA_EXPECTED) == 0 ? 1 : 0; \
1645 check_float (test_name, FUNC_TEST (FUNC_NAME) (ARG, &(EXTRA_VAR)), \
1646 EXPECTED, EXCEPTIONS); \
1647 EXTRA_OUTPUT_TEST_SETUP (ARG_STR, 1); \
1648 if (EXTRA_TEST) \
1649 check_float (extra1_name, EXTRA_VAR, EXTRA_EXPECTED, 0); \
1650 EXTRA_OUTPUT_TEST_CLEANUP (1); \
1651 COMMON_TEST_CLEANUP; \
1652 } \
1653 while (0)
1654 #define RUN_TEST_LOOP_fF_f1(FUNC_NAME, ARRAY, ROUNDING_MODE, EXTRA_VAR) \
1655 IF_ROUND_INIT_ ## ROUNDING_MODE \
1656 for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++) \
1657 RUN_TEST_fF_f1 ((ARRAY)[i].arg_str, FUNC_NAME, (ARRAY)[i].arg, \
1658 (ARRAY)[i].RM_##ROUNDING_MODE.expected, \
1659 (ARRAY)[i].RM_##ROUNDING_MODE.exceptions, \
1660 EXTRA_VAR, \
1661 (ARRAY)[i].RM_##ROUNDING_MODE.extra_test, \
1662 (ARRAY)[i].RM_##ROUNDING_MODE.extra_expected); \
1663 ROUND_RESTORE_ ## ROUNDING_MODE
1664 #define RUN_TEST_fI_f1(ARG_STR, FUNC_NAME, ARG, EXPECTED, \
1665 EXCEPTIONS, EXTRA_VAR, EXTRA_TEST, \
1666 EXTRA_EXPECTED) \
1667 do \
1668 if (enable_test (EXCEPTIONS)) \
1669 { \
1670 COMMON_TEST_SETUP (ARG_STR); \
1671 (EXTRA_VAR) = (EXTRA_EXPECTED) == 0 ? 1 : 0; \
1672 check_float (test_name, FUNC_TEST (FUNC_NAME) (ARG, &(EXTRA_VAR)), \
1673 EXPECTED, EXCEPTIONS); \
1674 EXTRA_OUTPUT_TEST_SETUP (ARG_STR, 1); \
1675 if (EXTRA_TEST) \
1676 check_int (extra1_name, EXTRA_VAR, EXTRA_EXPECTED, 0); \
1677 EXTRA_OUTPUT_TEST_CLEANUP (1); \
1678 COMMON_TEST_CLEANUP; \
1679 } \
1680 while (0)
1681 #define RUN_TEST_LOOP_fI_f1(FUNC_NAME, ARRAY, ROUNDING_MODE, EXTRA_VAR) \
1682 IF_ROUND_INIT_ ## ROUNDING_MODE \
1683 for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++) \
1684 RUN_TEST_fI_f1 ((ARRAY)[i].arg_str, FUNC_NAME, (ARRAY)[i].arg, \
1685 (ARRAY)[i].RM_##ROUNDING_MODE.expected, \
1686 (ARRAY)[i].RM_##ROUNDING_MODE.exceptions, \
1687 EXTRA_VAR, \
1688 (ARRAY)[i].RM_##ROUNDING_MODE.extra_test, \
1689 (ARRAY)[i].RM_##ROUNDING_MODE.extra_expected); \
1690 ROUND_RESTORE_ ## ROUNDING_MODE
1691 #define RUN_TEST_ffI_f1_mod8(ARG_STR, FUNC_NAME, ARG1, ARG2, EXPECTED, \
1692 EXCEPTIONS, EXTRA_VAR, EXTRA_TEST, \
1693 EXTRA_EXPECTED) \
1694 do \
1695 if (enable_test (EXCEPTIONS)) \
1696 { \
1697 COMMON_TEST_SETUP (ARG_STR); \
1698 (EXTRA_VAR) = (EXTRA_EXPECTED) == 0 ? 1 : 0; \
1699 check_float (test_name, \
1700 FUNC_TEST (FUNC_NAME) (ARG1, ARG2, &(EXTRA_VAR)), \
1701 EXPECTED, EXCEPTIONS); \
1702 EXTRA_OUTPUT_TEST_SETUP (ARG_STR, 1); \
1703 if (EXTRA_TEST) \
1704 check_int (extra1_name, (EXTRA_VAR) % 8, EXTRA_EXPECTED, 0); \
1705 EXTRA_OUTPUT_TEST_CLEANUP (1); \
1706 COMMON_TEST_CLEANUP; \
1707 } \
1708 while (0)
1709 #define RUN_TEST_LOOP_ffI_f1_mod8(FUNC_NAME, ARRAY, ROUNDING_MODE, \
1710 EXTRA_VAR) \
1711 IF_ROUND_INIT_ ## ROUNDING_MODE \
1712 for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++) \
1713 RUN_TEST_ffI_f1_mod8 ((ARRAY)[i].arg_str, FUNC_NAME, \
1714 (ARRAY)[i].arg1, (ARRAY)[i].arg2, \
1715 (ARRAY)[i].RM_##ROUNDING_MODE.expected, \
1716 (ARRAY)[i].RM_##ROUNDING_MODE.exceptions, \
1717 EXTRA_VAR, \
1718 (ARRAY)[i].RM_##ROUNDING_MODE.extra_test, \
1719 (ARRAY)[i].RM_##ROUNDING_MODE.extra_expected); \
1720 ROUND_RESTORE_ ## ROUNDING_MODE
1721 #define RUN_TEST_Ff_b1(ARG_STR, FUNC_NAME, ARG, EXPECTED, \
1722 EXCEPTIONS, EXTRA_VAR, EXTRA_TEST, \
1723 EXTRA_EXPECTED) \
1724 do \
1725 if (enable_test (EXCEPTIONS)) \
1726 { \
1727 COMMON_TEST_SETUP (ARG_STR); \
1728 (EXTRA_VAR) = (EXTRA_EXPECTED) == 0 ? 1 : 0; \
1729 /* Clear any exceptions from comparison involving sNaN \
1730 EXTRA_EXPECTED. */ \
1731 feclearexcept (FE_ALL_EXCEPT); \
1732 check_bool (test_name, FUNC_TEST (FUNC_NAME) (&(EXTRA_VAR), \
1733 (ARG)), \
1734 EXPECTED, EXCEPTIONS); \
1735 EXTRA_OUTPUT_TEST_SETUP (ARG_STR, 1); \
1736 if (EXTRA_TEST) \
1737 check_float (extra1_name, EXTRA_VAR, EXTRA_EXPECTED, \
1738 (EXCEPTIONS) & TEST_NAN_PAYLOAD); \
1739 EXTRA_OUTPUT_TEST_CLEANUP (1); \
1740 COMMON_TEST_CLEANUP; \
1741 } \
1742 while (0)
1743 #define RUN_TEST_LOOP_Ff_b1(FUNC_NAME, ARRAY, ROUNDING_MODE, \
1744 EXTRA_VAR) \
1745 IF_ROUND_INIT_ ## ROUNDING_MODE \
1746 for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++) \
1747 RUN_TEST_Ff_b1 ((ARRAY)[i].arg_str, FUNC_NAME, (ARRAY)[i].arg, \
1748 (ARRAY)[i].RM_##ROUNDING_MODE.expected, \
1749 (ARRAY)[i].RM_##ROUNDING_MODE.exceptions, \
1750 EXTRA_VAR, \
1751 (ARRAY)[i].RM_##ROUNDING_MODE.extra_test, \
1752 (ARRAY)[i].RM_##ROUNDING_MODE.extra_expected); \
1753 ROUND_RESTORE_ ## ROUNDING_MODE
1754 #define RUN_TEST_Ffp_b1(ARG_STR, FUNC_NAME, ARG, EXPECTED, \
1755 EXCEPTIONS, EXTRA_VAR, EXTRA_TEST, \
1756 EXTRA_EXPECTED) \
1757 do \
1758 if (enable_test (EXCEPTIONS)) \
1759 { \
1760 COMMON_TEST_SETUP (ARG_STR); \
1761 (EXTRA_VAR) = (EXTRA_EXPECTED) == 0 ? 1 : 0; \
1762 check_bool (test_name, FUNC_TEST (FUNC_NAME) (&(EXTRA_VAR), \
1763 &(ARG)), \
1764 EXPECTED, EXCEPTIONS); \
1765 EXTRA_OUTPUT_TEST_SETUP (ARG_STR, 1); \
1766 if (EXTRA_TEST) \
1767 check_float (extra1_name, EXTRA_VAR, EXTRA_EXPECTED, \
1768 (EXCEPTIONS) & TEST_NAN_PAYLOAD); \
1769 EXTRA_OUTPUT_TEST_CLEANUP (1); \
1770 COMMON_TEST_CLEANUP; \
1771 } \
1772 while (0)
1773 #define RUN_TEST_LOOP_Ffp_b1(FUNC_NAME, ARRAY, ROUNDING_MODE, \
1774 EXTRA_VAR) \
1775 IF_ROUND_INIT_ ## ROUNDING_MODE \
1776 for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++) \
1777 RUN_TEST_Ffp_b1 ((ARRAY)[i].arg_str, FUNC_NAME, (ARRAY)[i].arg, \
1778 (ARRAY)[i].RM_##ROUNDING_MODE.expected, \
1779 (ARRAY)[i].RM_##ROUNDING_MODE.exceptions, \
1780 EXTRA_VAR, \
1781 (ARRAY)[i].RM_##ROUNDING_MODE.extra_test, \
1782 (ARRAY)[i].RM_##ROUNDING_MODE.extra_expected); \
1783 ROUND_RESTORE_ ## ROUNDING_MODE
1784 #define RUN_TEST_c_c(ARG_STR, FUNC_NAME, ARGR, ARGC, EXPR, EXPC, \
1785 EXCEPTIONS) \
1786 do \
1787 if (enable_test (EXCEPTIONS)) \
1788 { \
1789 COMMON_TEST_SETUP (ARG_STR); \
1790 check_complex (test_name, \
1791 FUNC_TEST (FUNC_NAME) (BUILD_COMPLEX (ARGR, ARGC)), \
1792 BUILD_COMPLEX (EXPR, EXPC), EXCEPTIONS); \
1793 COMMON_TEST_CLEANUP; \
1794 } \
1795 while (0)
1796 #define RUN_TEST_LOOP_c_c(FUNC_NAME, ARRAY, ROUNDING_MODE) \
1797 IF_ROUND_INIT_ ## ROUNDING_MODE \
1798 for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++) \
1799 RUN_TEST_c_c ((ARRAY)[i].arg_str, FUNC_NAME, (ARRAY)[i].argr, \
1800 (ARRAY)[i].argc, \
1801 (ARRAY)[i].RM_##ROUNDING_MODE.expr, \
1802 (ARRAY)[i].RM_##ROUNDING_MODE.expc, \
1803 (ARRAY)[i].RM_##ROUNDING_MODE.exceptions); \
1804 ROUND_RESTORE_ ## ROUNDING_MODE
1805 #define RUN_TEST_cc_c(ARG_STR, FUNC_NAME, ARG1R, ARG1C, ARG2R, ARG2C, \
1806 EXPR, EXPC, EXCEPTIONS) \
1807 do \
1808 if (enable_test (EXCEPTIONS)) \
1809 { \
1810 COMMON_TEST_SETUP (ARG_STR); \
1811 check_complex (test_name, \
1812 FUNC_TEST (FUNC_NAME) (BUILD_COMPLEX (ARG1R, ARG1C), \
1813 BUILD_COMPLEX (ARG2R, ARG2C)), \
1814 BUILD_COMPLEX (EXPR, EXPC), EXCEPTIONS); \
1815 COMMON_TEST_CLEANUP; \
1816 } \
1817 while (0)
1818 #define RUN_TEST_LOOP_cc_c(FUNC_NAME, ARRAY, ROUNDING_MODE) \
1819 IF_ROUND_INIT_ ## ROUNDING_MODE \
1820 for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++) \
1821 RUN_TEST_cc_c ((ARRAY)[i].arg_str, FUNC_NAME, (ARRAY)[i].arg1r, \
1822 (ARRAY)[i].arg1c, (ARRAY)[i].arg2r, \
1823 (ARRAY)[i].arg2c, \
1824 (ARRAY)[i].RM_##ROUNDING_MODE.expr, \
1825 (ARRAY)[i].RM_##ROUNDING_MODE.expc, \
1826 (ARRAY)[i].RM_##ROUNDING_MODE.exceptions); \
1827 ROUND_RESTORE_ ## ROUNDING_MODE
1828 #define RUN_TEST_f_i(ARG_STR, FUNC_NAME, ARG, EXPECTED, EXCEPTIONS) \
1829 do \
1830 if (enable_test (EXCEPTIONS)) \
1831 { \
1832 COMMON_TEST_SETUP (ARG_STR); \
1833 check_int (test_name, FUNC_TEST (FUNC_NAME) (ARG), EXPECTED, \
1834 EXCEPTIONS); \
1835 COMMON_TEST_CLEANUP; \
1836 } \
1837 while (0)
1838 #define RUN_TEST_LOOP_f_i(FUNC_NAME, ARRAY, ROUNDING_MODE) \
1839 IF_ROUND_INIT_ ## ROUNDING_MODE \
1840 for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++) \
1841 RUN_TEST_f_i ((ARRAY)[i].arg_str, FUNC_NAME, (ARRAY)[i].arg, \
1842 (ARRAY)[i].RM_##ROUNDING_MODE.expected, \
1843 (ARRAY)[i].RM_##ROUNDING_MODE.exceptions); \
1844 ROUND_RESTORE_ ## ROUNDING_MODE
1845 #define RUN_TEST_f_i_tg(ARG_STR, FUNC_NAME, ARG, EXPECTED, \
1846 EXCEPTIONS) \
1847 do \
1848 if (enable_test (EXCEPTIONS)) \
1849 { \
1850 COMMON_TEST_SETUP (ARG_STR); \
1851 check_int (test_name, FUNC_NAME (ARG), EXPECTED, EXCEPTIONS); \
1852 COMMON_TEST_CLEANUP; \
1853 } \
1854 while (0)
1855 #define RUN_TEST_LOOP_f_i_tg(FUNC_NAME, ARRAY, ROUNDING_MODE) \
1856 IF_ROUND_INIT_ ## ROUNDING_MODE \
1857 for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++) \
1858 RUN_TEST_f_i_tg ((ARRAY)[i].arg_str, FUNC_NAME, (ARRAY)[i].arg, \
1859 (ARRAY)[i].RM_##ROUNDING_MODE.expected, \
1860 (ARRAY)[i].RM_##ROUNDING_MODE.exceptions); \
1861 ROUND_RESTORE_ ## ROUNDING_MODE
1862 #define RUN_TEST_ff_b(ARG_STR, FUNC_NAME, ARG1, ARG2, EXPECTED, \
1863 EXCEPTIONS) \
1864 do \
1865 if (enable_test (EXCEPTIONS)) \
1866 { \
1867 COMMON_TEST_SETUP (ARG_STR); \
1868 check_bool (test_name, FUNC_TEST (FUNC_NAME) (ARG1, ARG2), \
1869 EXPECTED, EXCEPTIONS); \
1870 COMMON_TEST_CLEANUP; \
1871 } \
1872 while (0)
1873 #define RUN_TEST_LOOP_ff_b(FUNC_NAME, ARRAY, ROUNDING_MODE) \
1874 IF_ROUND_INIT_ ## ROUNDING_MODE \
1875 for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++) \
1876 RUN_TEST_ff_b ((ARRAY)[i].arg_str, FUNC_NAME, \
1877 (ARRAY)[i].arg1, (ARRAY)[i].arg2, \
1878 (ARRAY)[i].RM_##ROUNDING_MODE.expected, \
1879 (ARRAY)[i].RM_##ROUNDING_MODE.exceptions); \
1880 ROUND_RESTORE_ ## ROUNDING_MODE
1881 #define RUN_TEST_ff_i_tg(ARG_STR, FUNC_NAME, ARG1, ARG2, EXPECTED, \
1882 EXCEPTIONS) \
1883 do \
1884 if (enable_test (EXCEPTIONS)) \
1885 { \
1886 COMMON_TEST_SETUP (ARG_STR); \
1887 check_int (test_name, FUNC_NAME (ARG1, ARG2), EXPECTED, \
1888 EXCEPTIONS); \
1889 COMMON_TEST_CLEANUP; \
1890 } \
1891 while (0)
1892 #define RUN_TEST_LOOP_ff_i_tg(FUNC_NAME, ARRAY, ROUNDING_MODE) \
1893 IF_ROUND_INIT_ ## ROUNDING_MODE \
1894 for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++) \
1895 RUN_TEST_ff_i_tg ((ARRAY)[i].arg_str, FUNC_NAME, \
1896 (ARRAY)[i].arg1, (ARRAY)[i].arg2, \
1897 (ARRAY)[i].RM_##ROUNDING_MODE.expected, \
1898 (ARRAY)[i].RM_##ROUNDING_MODE.exceptions); \
1899 ROUND_RESTORE_ ## ROUNDING_MODE
1900 #define RUN_TEST_f_b(ARG_STR, FUNC_NAME, ARG, EXPECTED, EXCEPTIONS) \
1901 do \
1902 if (enable_test (EXCEPTIONS)) \
1903 { \
1904 COMMON_TEST_SETUP (ARG_STR); \
1905 check_bool (test_name, FUNC_TEST (FUNC_NAME) (ARG), EXPECTED, \
1906 EXCEPTIONS); \
1907 COMMON_TEST_CLEANUP; \
1908 } \
1909 while (0)
1910 #define RUN_TEST_LOOP_f_b(FUNC_NAME, ARRAY, ROUNDING_MODE) \
1911 IF_ROUND_INIT_ ## ROUNDING_MODE \
1912 for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++) \
1913 RUN_TEST_f_b ((ARRAY)[i].arg_str, FUNC_NAME, (ARRAY)[i].arg, \
1914 (ARRAY)[i].RM_##ROUNDING_MODE.expected, \
1915 (ARRAY)[i].RM_##ROUNDING_MODE.exceptions); \
1916 ROUND_RESTORE_ ## ROUNDING_MODE
1917 #define RUN_TEST_f_b_tg(ARG_STR, FUNC_NAME, ARG, EXPECTED, \
1918 EXCEPTIONS) \
1919 do \
1920 if (enable_test (EXCEPTIONS)) \
1921 { \
1922 COMMON_TEST_SETUP (ARG_STR); \
1923 check_bool (test_name, FUNC_NAME (ARG), EXPECTED, EXCEPTIONS); \
1924 COMMON_TEST_CLEANUP; \
1925 } \
1926 while (0)
1927 #define RUN_TEST_LOOP_f_b_tg(FUNC_NAME, ARRAY, ROUNDING_MODE) \
1928 IF_ROUND_INIT_ ## ROUNDING_MODE \
1929 for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++) \
1930 RUN_TEST_f_b_tg ((ARRAY)[i].arg_str, FUNC_NAME, (ARRAY)[i].arg, \
1931 (ARRAY)[i].RM_##ROUNDING_MODE.expected, \
1932 (ARRAY)[i].RM_##ROUNDING_MODE.exceptions); \
1933 ROUND_RESTORE_ ## ROUNDING_MODE
1934 #define RUN_TEST_f_l(ARG_STR, FUNC_NAME, ARG, EXPECTED, EXCEPTIONS) \
1935 do \
1936 if (enable_test (EXCEPTIONS)) \
1937 { \
1938 COMMON_TEST_SETUP (ARG_STR); \
1939 check_long (test_name, FUNC_TEST (FUNC_NAME) (ARG), EXPECTED, \
1940 EXCEPTIONS); \
1941 COMMON_TEST_CLEANUP; \
1942 } \
1943 while (0)
1944 #define RUN_TEST_LOOP_f_l(FUNC_NAME, ARRAY, ROUNDING_MODE) \
1945 IF_ROUND_INIT_ ## ROUNDING_MODE \
1946 for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++) \
1947 RUN_TEST_f_l ((ARRAY)[i].arg_str, FUNC_NAME, (ARRAY)[i].arg, \
1948 (ARRAY)[i].RM_##ROUNDING_MODE.expected, \
1949 (ARRAY)[i].RM_##ROUNDING_MODE.exceptions); \
1950 ROUND_RESTORE_ ## ROUNDING_MODE
1951 #define RUN_TEST_f_L(ARG_STR, FUNC_NAME, ARG, EXPECTED, EXCEPTIONS) \
1952 do \
1953 if (enable_test (EXCEPTIONS)) \
1954 { \
1955 COMMON_TEST_SETUP (ARG_STR); \
1956 check_longlong (test_name, FUNC_TEST (FUNC_NAME) (ARG), \
1957 EXPECTED, EXCEPTIONS); \
1958 COMMON_TEST_CLEANUP; \
1959 } \
1960 while (0)
1961 #define RUN_TEST_LOOP_f_L(FUNC_NAME, ARRAY, ROUNDING_MODE) \
1962 IF_ROUND_INIT_ ## ROUNDING_MODE \
1963 for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++) \
1964 RUN_TEST_f_L ((ARRAY)[i].arg_str, FUNC_NAME, (ARRAY)[i].arg, \
1965 (ARRAY)[i].RM_##ROUNDING_MODE.expected, \
1966 (ARRAY)[i].RM_##ROUNDING_MODE.exceptions); \
1967 ROUND_RESTORE_ ## ROUNDING_MODE
1968 #define RUN_TEST_fFF_11(ARG_STR, FUNC_NAME, ARG, EXCEPTIONS, \
1969 EXTRA1_VAR, EXTRA1_TEST, \
1970 EXTRA1_EXPECTED, EXTRA2_VAR, \
1971 EXTRA2_TEST, EXTRA2_EXPECTED) \
1972 do \
1973 if (enable_test (EXCEPTIONS)) \
1974 { \
1975 COMMON_TEST_SETUP (ARG_STR); \
1976 FUNC_TEST (FUNC_NAME) (ARG, &(EXTRA1_VAR), &(EXTRA2_VAR)); \
1977 EXTRA_OUTPUT_TEST_SETUP (ARG_STR, 1); \
1978 if (EXTRA1_TEST) \
1979 check_float (extra1_name, EXTRA1_VAR, EXTRA1_EXPECTED, \
1980 EXCEPTIONS); \
1981 EXTRA_OUTPUT_TEST_CLEANUP (1); \
1982 EXTRA_OUTPUT_TEST_SETUP (ARG_STR, 2); \
1983 if (EXTRA2_TEST) \
1984 check_float (extra2_name, EXTRA2_VAR, EXTRA2_EXPECTED, 0); \
1985 EXTRA_OUTPUT_TEST_CLEANUP (2); \
1986 COMMON_TEST_CLEANUP; \
1987 } \
1988 while (0)
1989 #define RUN_TEST_LOOP_fFF_11(FUNC_NAME, ARRAY, ROUNDING_MODE, \
1990 EXTRA1_VAR, EXTRA2_VAR) \
1991 IF_ROUND_INIT_ ## ROUNDING_MODE \
1992 for (size_t i = 0; i < sizeof (ARRAY) / sizeof (ARRAY)[0]; i++) \
1993 RUN_TEST_fFF_11 ((ARRAY)[i].arg_str, FUNC_NAME, (ARRAY)[i].arg, \
1994 (ARRAY)[i].RM_##ROUNDING_MODE.exceptions, \
1995 EXTRA1_VAR, \
1996 (ARRAY)[i].RM_##ROUNDING_MODE.extra1_test, \
1997 (ARRAY)[i].RM_##ROUNDING_MODE.extra1_expected, \
1998 EXTRA2_VAR, \
1999 (ARRAY)[i].RM_##ROUNDING_MODE.extra2_test, \
2000 (ARRAY)[i].RM_##ROUNDING_MODE.extra2_expected); \
2001 ROUND_RESTORE_ ## ROUNDING_MODE
2002
2003 #if !TEST_MATHVEC
2004 # define VEC_SUFF
2005 #endif
2006
2007 #define STR_CONCAT(a, b, c) __STRING (a##b##c)
2008 #define STR_CON3(a, b, c) STR_CONCAT (a, b, c)
2009
2010 /* This generated header defines series of macros started with HAVE_VECTOR_. */
2011 #include "libm-have-vector-test.h"
2012
2013 #define HAVE_VECTOR(func) __CONCAT (HAVE_VECTOR_, func)
2014
2015 /* Start and end the tests for a given function. */
2016 #define START(FUN, SUFF, EXACT) \
2017 CHECK_ARCH_EXT; \
2018 if (TEST_MATHVEC && !HAVE_VECTOR (FUNC (FUN))) return; \
2019 const char *this_func = STR_CON3 (FUN, SUFF, VEC_SUFF); \
2020 init_max_error (this_func, EXACT)
2021 #define END \
2022 print_max_error (this_func)
2023 #define END_COMPLEX \
2024 print_complex_max_error (this_func)
2025
2026 /* Run tests for a given function in all rounding modes. */
2027 #define ALL_RM_TEST(FUNC, EXACT, ARRAY, LOOP_MACRO, END_MACRO, ...) \
2028 do \
2029 { \
2030 do \
2031 { \
2032 START (FUNC,, EXACT); \
2033 LOOP_MACRO (FUNC, ARRAY, , ## __VA_ARGS__); \
2034 END_MACRO; \
2035 } \
2036 while (0); \
2037 do \
2038 { \
2039 START (FUNC, _downward, EXACT); \
2040 LOOP_MACRO (FUNC, ARRAY, FE_DOWNWARD, ## __VA_ARGS__); \
2041 END_MACRO; \
2042 } \
2043 while (0); \
2044 do \
2045 { \
2046 START (FUNC, _towardzero, EXACT); \
2047 LOOP_MACRO (FUNC, ARRAY, FE_TOWARDZERO, ## __VA_ARGS__); \
2048 END_MACRO; \
2049 } \
2050 while (0); \
2051 do \
2052 { \
2053 START (FUNC, _upward, EXACT); \
2054 LOOP_MACRO (FUNC, ARRAY, FE_UPWARD, ## __VA_ARGS__); \
2055 END_MACRO; \
2056 } \
2057 while (0); \
2058 } \
2059 while (0);
2060
2061 /* This is to prevent messages from the SVID libm emulation. */
2062 int
2063 matherr (struct exception *x __attribute__ ((unused)))
2064 {
2065 return 1;
2066 }
2067
2068 static void
2069 initialize (void)
2070 {
2071 fpstack_test ("start *init*");
2072
2073 /* Clear all exceptions. From now on we must not get random exceptions. */
2074 feclearexcept (FE_ALL_EXCEPT);
2075 errno = 0;
2076
2077 /* Test to make sure we start correctly. */
2078 fpstack_test ("end *init*");
2079 }
2080
2081 /* Definitions of arguments for argp functions. */
2082 static const struct argp_option options[] =
2083 {
2084 { "verbose", 'v', "NUMBER", 0, "Level of verbosity (0..3)"},
2085 { "ulps-file", 'u', NULL, 0, "Output ulps to file ULPs"},
2086 { "no-max-error", 'f', NULL, 0,
2087 "Don't output maximal errors of functions"},
2088 { "no-points", 'p', NULL, 0,
2089 "Don't output results of functions invocations"},
2090 { "ignore-max-ulp", 'i', "yes/no", 0,
2091 "Ignore given maximal errors"},
2092 { "output-dir", 'o', "DIR", 0,
2093 "Directory where generated files will be placed"},
2094 { NULL, 0, NULL, 0, NULL }
2095 };
2096
2097 /* Short description of program. */
2098 static const char doc[] = "Math test suite: " TEST_MSG ;
2099
2100 /* Prototype for option handler. */
2101 static error_t parse_opt (int key, char *arg, struct argp_state *state);
2102
2103 /* Data structure to communicate with argp functions. */
2104 static struct argp argp =
2105 {
2106 options, parse_opt, NULL, doc,
2107 };
2108
2109
2110 /* Handle program arguments. */
2111 static error_t
2112 parse_opt (int key, char *arg, struct argp_state *state)
2113 {
2114 switch (key)
2115 {
2116 case 'f':
2117 output_max_error = 0;
2118 break;
2119 case 'i':
2120 if (strcmp (arg, "yes") == 0)
2121 ignore_max_ulp = 1;
2122 else if (strcmp (arg, "no") == 0)
2123 ignore_max_ulp = 0;
2124 break;
2125 case 'o':
2126 output_dir = (char *) malloc (strlen (arg) + 1);
2127 if (output_dir != NULL)
2128 strcpy (output_dir, arg);
2129 else
2130 return errno;
2131 break;
2132 case 'p':
2133 output_points = 0;
2134 break;
2135 case 'u':
2136 output_ulps = 1;
2137 break;
2138 case 'v':
2139 if (optarg)
2140 verbose = (unsigned int) strtoul (optarg, NULL, 0);
2141 else
2142 verbose = 3;
2143 break;
2144 default:
2145 return ARGP_ERR_UNKNOWN;
2146 }
2147 return 0;
2148 }
2149
2150 /* Verify that our ulp () implementation is behaving as expected
2151 or abort. */
2152 void
2153 check_ulp (void)
2154 {
2155 FLOAT ulps, ulpx, value;
2156 int i;
2157 /* Check ulp of zero is a subnormal value... */
2158 ulps = ulp (0x0.0p0);
2159 if (fpclassify (ulps) != FP_SUBNORMAL)
2160 {
2161 fprintf (stderr, "ulp (0x0.0p0) is not FP_SUBNORMAL!\n");
2162 exit (EXIT_FAILURE);
2163 }
2164 /* Check that the ulp of one is a normal value... */
2165 ulps = ulp (1.0L);
2166 if (fpclassify (ulps) != FP_NORMAL)
2167 {
2168 fprintf (stderr, "ulp (1.0L) is not FP_NORMAL\n");
2169 exit (EXIT_FAILURE);
2170 }
2171
2172 /* Compute the next subnormal value using nextafter to validate ulp.
2173 We allow +/- 1 ulp around the represented value. */
2174 value = FUNC(nextafter) (0, 1);
2175 ulps = ULPDIFF (value, 0);
2176 ulpx = ulp (1.0L);
2177 if (ulps < (1.0L - ulpx) || ulps > (1.0L + ulpx))
2178 {
2179 fprintf (stderr, "Value outside of 1 +/- 1ulp.\n");
2180 exit (EXIT_FAILURE);
2181 }
2182 /* Compute the nearest representable number from 10 towards 20.
2183 The result is 10 + 1ulp. We use this to check the ulp function.
2184 We allow +/- 1 ulp around the represented value. */
2185 value = FUNC(nextafter) (10, 20);
2186 ulps = ULPDIFF (value, 10);
2187 ulpx = ulp (1.0L);
2188 if (ulps < (1.0L - ulpx) || ulps > (1.0L + ulpx))
2189 {
2190 fprintf (stderr, "Value outside of 1 +/- 1ulp.\n");
2191 exit (EXIT_FAILURE);
2192 }
2193 /* This gives one more ulp. */
2194 value = FUNC(nextafter) (value, 20);
2195 ulps = ULPDIFF (value, 10);
2196 ulpx = ulp (2.0L);
2197 if (ulps < (2.0L - ulpx) || ulps > (2.0L + ulpx))
2198 {
2199 fprintf (stderr, "Value outside of 2 +/- 1ulp.\n");
2200 exit (EXIT_FAILURE);
2201 }
2202 /* And now calculate 100 ulp. */
2203 for (i = 2; i < 100; i++)
2204 value = FUNC(nextafter) (value, 20);
2205 ulps = ULPDIFF (value, 10);
2206 ulpx = ulp (100.0L);
2207 if (ulps < (100.0L - ulpx) || ulps > (100.0L + ulpx))
2208 {
2209 fprintf (stderr, "Value outside of 100 +/- 1ulp.\n");
2210 exit (EXIT_FAILURE);
2211 }
2212 }
2213
2214 static void do_test (void);
2215
2216 int
2217 main (int argc, char **argv)
2218 {
2219
2220 int remaining;
2221 char *ulps_file_path;
2222 size_t dir_len = 0;
2223
2224 verbose = 1;
2225 output_ulps = 0;
2226 output_max_error = 1;
2227 output_points = 1;
2228 output_dir = NULL;
2229 /* XXX set to 0 for releases. */
2230 ignore_max_ulp = 0;
2231
2232 /* Parse and process arguments. */
2233 argp_parse (&argp, argc, argv, 0, &remaining, NULL);
2234
2235 if (remaining != argc)
2236 {
2237 fprintf (stderr, "wrong number of arguments");
2238 argp_help (&argp, stdout, ARGP_HELP_SEE, program_invocation_short_name);
2239 exit (EXIT_FAILURE);
2240 }
2241
2242 if (output_ulps)
2243 {
2244 if (output_dir != NULL)
2245 dir_len = strlen (output_dir);
2246 ulps_file_path = (char *) malloc (dir_len + strlen (ulps_file_name) + 1);
2247 if (ulps_file_path == NULL)
2248 {
2249 perror ("can't allocate path for `ULPs' file: ");
2250 exit (1);
2251 }
2252 sprintf (ulps_file_path, "%s%s", output_dir == NULL ? "" : output_dir, ulps_file_name);
2253 ulps_file = fopen (ulps_file_path, "a");
2254 if (ulps_file == NULL)
2255 {
2256 perror ("can't open file `ULPs' for writing: ");
2257 exit (1);
2258 }
2259 }
2260
2261
2262 initialize ();
2263 printf (TEST_MSG);
2264
2265 INIT_ARCH_EXT;
2266
2267 check_ulp ();
2268
2269 do_test ();
2270
2271 if (output_ulps)
2272 fclose (ulps_file);
2273
2274 printf ("\nTest suite completed:\n");
2275 printf (" %d test cases plus %d tests for exception flags and\n"
2276 " %d tests for errno executed.\n",
2277 noTests, noExcTests, noErrnoTests);
2278 if (noErrors)
2279 {
2280 printf (" %d errors occurred.\n", noErrors);
2281 return 1;
2282 }
2283 printf (" All tests passed successfully.\n");
2284
2285 return 0;
2286 }
This page took 0.150243 seconds and 6 git commands to generate.