]> git.ipfire.org Git - thirdparty/glibc.git/blob - math/libm-test-support.c
31ae9902e6197553564d9520a68eb43414465045
[thirdparty/glibc.git] / math / libm-test-support.c
1 /* Support code for testing libm functions (compiled once per type).
2 Copyright (C) 1997-2025 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 <https://www.gnu.org/licenses/>. */
18
19 /* Part of testsuite for libm.
20
21 libm-test-support.c contains functions shared by tests of different
22 libm functions and types; it is compiled once per type.
23 libm-test-driver.c defines the main function, and various variables
24 that are used to configure the code in libm-test-support.c for
25 different types and for variants such as testing inline functions.
26
27 The tests of individual functions are in .inc files processed by
28 gen-libm-test.py, with the resulting files included together with
29 libm-test-driver.c.
30
31 The per-type headers included both before libm-test-support.c and
32 for the tests of individual functions must define the following
33 macros:
34
35 FUNC(function): Convert general function name (like cos) to name
36 with correct suffix (e.g. cosl or cosf).
37
38 FLOAT: Floating-point type to test.
39
40 BUILD_COMPLEX(real, imag): Create a complex number by calling a
41 macro such as CMPLX.
42
43 PREFIX: The prefix for <float.h> macros for the type (e.g. LDBL,
44 DBL, or FLT).
45
46 TYPE_STR: The name of the type as used in ulps files, as a string.
47
48 ULP_IDX: The array indexes for ulps values for this function.
49
50 LIT: Append the correct suffix to a literal.
51
52 LITM: Append the correct suffix to an M_* macro name.
53
54 FTOSTR: A function similar in type to strfromf which converts a
55 FLOAT to a string.
56
57 snan_value_MACRO: The macro such as SNAN for a signaling NaN for
58 the type.
59
60 */
61
62 /* Parameter handling is primitive in the moment:
63 --verbose=[0..3] for different levels of output:
64 0: only error count
65 1: basic report on failed tests (default)
66 2: full report on all tests
67 -v for full output (equals --verbose=3)
68 -u for generation of an ULPs file
69 */
70
71 /* "Philosophy":
72
73 This suite tests some aspects of the correct implementation of
74 mathematical functions in libm. Some simple, specific parameters
75 are tested for correctness but there's no exhaustive
76 testing. Handling of specific inputs (e.g. infinity, not-a-number)
77 is also tested. Correct handling of exceptions is checked
78 against. These implemented tests should check all cases that are
79 specified in ISO C99.
80
81 NaN values: The payload of NaNs is set in inputs for functions
82 where it is significant, and is examined in the outputs of some
83 functions.
84
85 Inline functions: Inlining functions should give an improvement in
86 speed - but not in precision. The inlined functions return
87 reasonable values for a reasonable range of input values. The
88 result is not necessarily correct for all values and exceptions are
89 not correctly raised in all cases. Problematic input and return
90 values are infinity, not-a-number and minus zero. This suite
91 therefore does not check these specific inputs and the exception
92 handling for inlined mathematical functions - just the "reasonable"
93 values are checked.
94
95 Beware: The tests might fail for any of the following reasons:
96 - Tests are wrong
97 - Functions are wrong
98 - Floating Point Unit not working properly
99 - Compiler has errors
100
101 With e.g. gcc 2.7.2.2 the test for cexp fails because of a compiler error.
102
103
104 To Do: All parameter should be numbers that can be represented as
105 exact floating point values. Currently some values cannot be
106 represented exactly and therefore the result is not the expected
107 result. For this we will use 36 digits so that numbers can be
108 represented exactly. */
109
110 #include "libm-test-support.h"
111
112 #include <array_length.h>
113 #include <argp.h>
114 #include <errno.h>
115 #include <string.h>
116 #include <assert.h>
117 #include <stdbool.h>
118
119 /* This header defines func_ulps, func_real_ulps and func_imag_ulps
120 arrays. */
121 #include "libm-test-ulps.h"
122
123 /* Maximum character buffer to store a stringitized FLOAT value. */
124 #define FSTR_MAX (128)
125
126 #define ulps_file_name "ULPs" /* Name of the ULPs file. */
127 static FILE *ulps_file; /* File to document difference. */
128 static int output_ulps; /* Should ulps printed? */
129 static char *output_dir; /* Directory where generated files will be written. */
130
131 #define TEST_INPUT 1
132 #define TEST_MAXERROR 2
133 static int noErrors; /* number of errors */
134 static int noTests; /* number of tests (without testing exceptions) */
135 static int noMaxErrorTests; /* number of max error tests */
136 static int noExcTests; /* number of tests for exception flags */
137 static int noErrnoTests; /* number of tests for errno values */
138
139 static unsigned int verbose;
140 static int output_max_error; /* Should the maximal errors printed? */
141 static int output_points; /* Should the single function results printed? */
142 static int ignore_max_ulp; /* Should we ignore max_ulp? */
143 static int test_ibm128; /* Is argument or result IBM long double? */
144
145 static FLOAT max_error, real_max_error, imag_max_error;
146
147 static FLOAT prev_max_error, prev_real_max_error, prev_imag_max_error;
148
149 static FLOAT max_valid_error;
150
151 static bool is_complex = false;
152
153 /* Sufficient numbers of digits to represent any floating-point value
154 unambiguously (for any choice of the number of bits in the first
155 hex digit, in the case of TYPE_HEX_DIG). When used with printf
156 formats where the precision counts only digits after the point, 1
157 is subtracted from these values. */
158 #define TYPE_DECIMAL_DIG __CONCATX (PREFIX, _DECIMAL_DIG)
159 #define TYPE_HEX_DIG ((MANT_DIG + 6) / 4)
160
161 /* Converts VALUE (a floating-point number) to string and writes it to DEST.
162 PRECISION specifies the number of fractional digits that should be printed.
163 CONVERSION is the conversion specifier, such as in printf, e.g. 'f' or 'a'.
164 The output is prepended with an empty space if VALUE is non-negative. */
165 static void
166 fmt_ftostr (char *dest, size_t size, int precision, const char *conversion,
167 FLOAT value)
168 {
169 char format[64];
170 char *ptr_format;
171 int ret;
172
173 /* Generate the format string. */
174 ptr_format = stpcpy (format, "%.");
175 ret = sprintf (ptr_format, "%d", precision);
176 ptr_format += ret;
177 ptr_format = stpcpy (ptr_format, conversion);
178
179 /* Add a space to the beginning of the output string, if the floating-point
180 number is non-negative. This mimics the behavior of the space (' ') flag
181 in snprintf, which is not available on strfrom. */
182 if (! signbit (value))
183 {
184 *dest = ' ';
185 dest++;
186 size--;
187 }
188
189 /* Call the float to string conversion function, e.g.: strfromd. */
190 FTOSTR (dest, size, format, value);
191 }
192
193
194 static FLOAT
195 default_max_valid_error (int exact, int testing_ibm128)
196 {
197 if (testing_ibm128)
198 /* The documented accuracy of IBM long double division is 3ulp
199 (see libgcc/config/rs6000/ibm-ldouble-format), so do not
200 require better accuracy for libm functions that are exactly
201 defined for other formats. */
202 return max_valid_error = exact ? 3 : 16;
203 else
204 return max_valid_error = exact ? 0 : 9;
205 }
206
207 /* Compare KEY (a string, with the name of a function) with ULP (a
208 pointer to a struct ulp_data structure), returning a value less
209 than, equal to or greater than zero for use in bsearch. */
210
211 static int
212 compare_ulp_data (const void *key, const void *ulp)
213 {
214 const char *keystr = key;
215 const struct ulp_data *ulpdat = ulp;
216 return strcmp (keystr, ulpdat->name);
217 }
218
219 static const int ulp_idx = ULP_IDX;
220
221 /* Return the ulps for NAME in array DATA with NMEMB elements, or 0 if
222 no ulps listed. */
223
224 static FLOAT
225 find_ulps (const char *name, const struct ulp_data *data, size_t nmemb,
226 int exact, int testing_ibm128)
227 {
228 const struct ulp_data *entry = bsearch (name, data, nmemb, sizeof (*data),
229 compare_ulp_data);
230 if (entry == NULL)
231 return default_max_valid_error (exact, testing_ibm128);
232 else
233 return entry->max_ulp[ulp_idx] == -1
234 ? default_max_valid_error (exact, testing_ibm128)
235 : entry->max_ulp[ulp_idx];
236 }
237
238 void
239 init_max_error (const char *name, int exact, int testing_ibm128)
240 {
241 max_error = 0;
242 real_max_error = 0;
243 imag_max_error = 0;
244 test_ibm128 = testing_ibm128;
245 prev_max_error = find_ulps (name, func_ulps, array_length (func_ulps),
246 exact, testing_ibm128);
247 prev_real_max_error = find_ulps (name, func_real_ulps,
248 array_length (func_real_ulps), exact,
249 testing_ibm128);
250 prev_imag_max_error = find_ulps (name, func_imag_ulps,
251 array_length (func_imag_ulps),
252 exact, testing_ibm128);
253 max_valid_error = default_max_valid_error (exact, testing_ibm128);
254 prev_max_error = (prev_max_error <= max_valid_error
255 ? prev_max_error
256 : max_valid_error);
257 prev_real_max_error = (prev_real_max_error <= max_valid_error
258 ? prev_real_max_error
259 : max_valid_error);
260 prev_imag_max_error = (prev_imag_max_error <= max_valid_error
261 ? prev_imag_max_error
262 : max_valid_error);
263 feclearexcept (FE_ALL_EXCEPT);
264 errno = 0;
265 }
266
267 static void
268 set_max_error (FLOAT current, FLOAT *curr_max_error)
269 {
270 if (current > *curr_max_error && current <= max_valid_error)
271 *curr_max_error = current;
272 }
273
274
275 /* Print a FLOAT. */
276 static void
277 print_float (FLOAT f)
278 {
279 /* As printf doesn't differ between a sNaN and a qNaN, do this manually. */
280 if (issignaling (f))
281 printf ("sNaN\n");
282 else if (isnan (f))
283 printf ("qNaN\n");
284 else
285 {
286 char fstrn[FSTR_MAX], fstrx[FSTR_MAX];
287 fmt_ftostr (fstrn, FSTR_MAX, TYPE_DECIMAL_DIG - 1, "e", f);
288 fmt_ftostr (fstrx, FSTR_MAX, TYPE_HEX_DIG - 1, "a", f);
289 printf ("%s %s\n", fstrn, fstrx);
290 }
291 }
292
293 /* Should the message print to screen? This depends on the verbose flag,
294 and the test status. */
295 static int
296 print_screen (int ok)
297 {
298 if (output_points
299 && (verbose > 1
300 || (verbose == 1 && ok == 0)))
301 return 1;
302 return 0;
303 }
304
305
306 /* Should the message print to screen? This depends on the verbose flag,
307 and the test status. */
308 static int
309 print_screen_max_error (int ok)
310 {
311 if (output_max_error
312 && (verbose > 1
313 || ((verbose == 1) && (ok == 0))))
314 return 1;
315 return 0;
316 }
317
318 /* Update statistic counters. */
319 static void
320 update_stats (int ok, int testType)
321 {
322 switch (testType)
323 {
324 case TEST_INPUT:
325 ++noTests;
326 break;
327 case TEST_MAXERROR:
328 ++noMaxErrorTests;
329 break;
330 default:
331 abort();
332 }
333 if (!ok)
334 ++noErrors;
335 }
336
337 static void
338 print_function_ulps (const char *function_name, FLOAT ulp)
339 {
340 if (output_ulps)
341 {
342 char ustrn[FSTR_MAX];
343 FTOSTR (ustrn, FSTR_MAX, "%.0f", FUNC (ceil) (ulp));
344 fprintf (ulps_file, "Function: \"%s\":\n", function_name);
345 fprintf (ulps_file, "%s: %s\n", qtype_str, ustrn);
346 }
347 }
348
349
350 static void
351 print_complex_function_ulps (const char *function_name, FLOAT real_ulp,
352 FLOAT imag_ulp)
353 {
354 if (output_ulps)
355 {
356 char fstrn[FSTR_MAX];
357 if (real_ulp != 0.0)
358 {
359 FTOSTR (fstrn, FSTR_MAX, "%.0f", FUNC (ceil) (real_ulp));
360 fprintf (ulps_file, "Function: Real part of \"%s\":\n", function_name);
361 fprintf (ulps_file, "%s: %s\n", qtype_str, fstrn);
362 }
363 if (imag_ulp != 0.0)
364 {
365 FTOSTR (fstrn, FSTR_MAX, "%.0f", FUNC (ceil) (imag_ulp));
366 fprintf (ulps_file, "Function: Imaginary part of \"%s\":\n", function_name);
367 fprintf (ulps_file, "%s: %s\n", qtype_str, fstrn);
368 }
369
370
371 }
372 }
373
374
375
376 /* Test if Floating-Point stack hasn't changed */
377 static void
378 fpstack_test (const char *test_name)
379 {
380 #if defined (__i386__) || defined (__x86_64__)
381 static int old_stack;
382 int sw;
383
384 asm ("fnstsw" : "=a" (sw));
385 sw >>= 11;
386 sw &= 7;
387
388 if (sw != old_stack)
389 {
390 printf ("FP-Stack wrong after test %s (%d, should be %d)\n",
391 test_name, sw, old_stack);
392 ++noErrors;
393 old_stack = sw;
394 }
395 #endif
396 }
397
398 static void
399 print_test_start (int test_num, const char *test_name, int test_type)
400 {
401 if (print_screen (1))
402 printf ("--- Start of%s test # %d, named \"%s\" ---\n",
403 test_type == TEST_MAXERROR ? " max error" : "", test_num, test_name);
404 }
405
406 static void
407 print_test_end (int test_num, const char *test_name, int test_type)
408 {
409 if (print_screen (1))
410 printf ("--- End of%s test # %d, named \"%s\" ---\n",
411 test_type == TEST_MAXERROR ? " max error" : "", test_num, test_name);
412 }
413
414 /* This is a builtin test of overall max error. */
415 void
416 check_max_error (const char *func_name)
417 {
418 int ok = 0;
419 int thisTest = noMaxErrorTests;
420
421 print_test_start (thisTest, func_name, TEST_MAXERROR);
422
423 if (max_error == 0.0 || (max_error <= prev_max_error && !ignore_max_ulp))
424 {
425 ok = 1;
426 }
427
428 if (!ok)
429 print_function_ulps (func_name, max_error);
430
431
432 if (print_screen_max_error (ok))
433 {
434 char mestr[FSTR_MAX], pmestr[FSTR_MAX];
435 FTOSTR (mestr, FSTR_MAX, "%.0f", FUNC (ceil) (max_error));
436 FTOSTR (pmestr, FSTR_MAX, "%.0f", FUNC (ceil) (prev_max_error));
437 printf ("Maximal error of `%s'\n", func_name);
438 printf (" is : %s ulp\n", mestr);
439 printf (" accepted: %s ulp\n", pmestr);
440 }
441
442 update_stats (ok, TEST_MAXERROR);
443
444 print_test_end (thisTest, func_name, TEST_MAXERROR);
445 }
446
447 /* This is a builtin test of overall max error. */
448 void
449 check_complex_max_error (const char *func_name)
450 {
451 int real_ok = 0, imag_ok = 0, ok;
452 int thisTest = noMaxErrorTests;
453
454 print_test_start (thisTest, func_name, TEST_MAXERROR);
455
456 if (real_max_error == 0
457 || (real_max_error <= prev_real_max_error && !ignore_max_ulp))
458 {
459 real_ok = 1;
460 }
461
462 if (imag_max_error == 0
463 || (imag_max_error <= prev_imag_max_error && !ignore_max_ulp))
464 {
465 imag_ok = 1;
466 }
467
468 ok = real_ok && imag_ok;
469
470 if (!ok)
471 print_complex_function_ulps (func_name,
472 real_ok ? 0 : real_max_error,
473 imag_ok ? 0 : imag_max_error);
474
475 if (print_screen_max_error (ok))
476 {
477 char rmestr[FSTR_MAX], prmestr[FSTR_MAX];
478 char imestr[FSTR_MAX], pimestr[FSTR_MAX];
479 FTOSTR (rmestr, FSTR_MAX, "%.0f", FUNC (ceil) (real_max_error));
480 FTOSTR (prmestr, FSTR_MAX, "%.0f", FUNC (ceil) (prev_real_max_error));
481 FTOSTR (imestr, FSTR_MAX, "%.0f", FUNC (ceil) (imag_max_error));
482 FTOSTR (pimestr, FSTR_MAX, "%.0f", FUNC (ceil) (prev_imag_max_error));
483 printf ("Maximal error of real part of: %s\n", func_name);
484 printf (" is : %s ulp\n", rmestr);
485 printf (" accepted: %s ulp\n", prmestr);
486 printf ("Maximal error of imaginary part of: %s\n", func_name);
487 printf (" is : %s ulp\n", imestr);
488 printf (" accepted: %s ulp\n", pimestr);
489 }
490
491 update_stats (ok, TEST_MAXERROR);
492 print_test_end (thisTest, func_name, TEST_MAXERROR);
493
494 is_complex = true;
495 }
496
497
498 #if FE_ALL_EXCEPT
499 /* Test whether a given exception was raised. */
500 static void
501 test_single_exception (const char *test_name,
502 int exception,
503 int exc_flag,
504 int fe_flag,
505 const char *flag_name)
506 {
507 int ok = 1;
508 if (exception & exc_flag)
509 {
510 if (fetestexcept (fe_flag))
511 {
512 if (print_screen (1))
513 printf ("Pass: %s: Exception \"%s\" set\n", test_name, flag_name);
514 }
515 else
516 {
517 ok = 0;
518 if (print_screen (0))
519 printf ("Failure: %s: Exception \"%s\" not set\n",
520 test_name, flag_name);
521 }
522 }
523 else
524 {
525 if (fetestexcept (fe_flag))
526 {
527 ok = 0;
528 if (print_screen (0))
529 printf ("Failure: %s: Exception \"%s\" set\n",
530 test_name, flag_name);
531 }
532 else
533 {
534 if (print_screen (1))
535 printf ("Pass: %s: Exception \"%s\" not set\n", test_name,
536 flag_name);
537 }
538 }
539 if (!ok)
540 ++noErrors;
541 ++noExcTests;
542 }
543 #endif
544
545 /* Test whether exceptions given by EXCEPTION are raised. Ignore thereby
546 allowed but not required exceptions.
547 */
548 static void
549 test_exceptions (const char *test_name, int exception)
550 {
551 if (flag_test_exceptions && EXCEPTION_TESTS (FLOAT))
552 {
553 int ran = 0;
554 #ifdef FE_DIVBYZERO
555 if ((exception & DIVIDE_BY_ZERO_EXCEPTION_OK) == 0)
556 {
557 test_single_exception (test_name, exception,
558 DIVIDE_BY_ZERO_EXCEPTION, FE_DIVBYZERO,
559 "Divide by zero");
560 ran = 1;
561 }
562 #endif
563 #ifdef FE_INVALID
564 if ((exception & INVALID_EXCEPTION_OK) == 0)
565 {
566 test_single_exception (test_name, exception,
567 INVALID_EXCEPTION, FE_INVALID,
568 "Invalid operation");
569 ran = 1;
570 }
571 #endif
572 #ifdef FE_OVERFLOW
573 if ((exception & OVERFLOW_EXCEPTION_OK) == 0)
574 {
575 test_single_exception (test_name, exception, OVERFLOW_EXCEPTION,
576 FE_OVERFLOW, "Overflow");
577 ran = 1;
578 }
579 #endif
580 /* Spurious "underflow" and "inexact" exceptions are always
581 allowed for IBM long double, in line with the underlying
582 arithmetic. */
583 #ifdef FE_UNDERFLOW
584 if ((exception & UNDERFLOW_EXCEPTION_OK) == 0
585 && !(test_ibm128
586 && (exception & UNDERFLOW_EXCEPTION) == 0))
587 {
588 test_single_exception (test_name, exception, UNDERFLOW_EXCEPTION,
589 FE_UNDERFLOW, "Underflow");
590 ran = 1;
591 }
592
593 #endif
594 #ifdef FE_INEXACT
595 if ((exception & (INEXACT_EXCEPTION | NO_INEXACT_EXCEPTION)) != 0
596 && !(test_ibm128
597 && (exception & NO_INEXACT_EXCEPTION) != 0))
598 {
599 test_single_exception (test_name, exception, INEXACT_EXCEPTION,
600 FE_INEXACT, "Inexact");
601 ran = 1;
602 }
603 #endif
604 assert (ran == 1);
605 }
606 else
607 {
608 if (print_screen (1))
609 printf ("Info: %s: No exceptions tested\n", test_name);
610 }
611 feclearexcept (FE_ALL_EXCEPT);
612 }
613
614 /* Test whether errno for TEST_NAME, set to ERRNO_VALUE, has value
615 EXPECTED_VALUE (description EXPECTED_NAME). */
616 static void
617 test_single_errno (const char *test_name, int errno_value,
618 int expected_value, const char *expected_name)
619 {
620 if (errno_value == expected_value)
621 {
622 if (print_screen (1))
623 printf ("Pass: %s: errno set to %d (%s)\n", test_name, errno_value,
624 expected_name);
625 }
626 else
627 {
628 ++noErrors;
629 if (print_screen (0))
630 printf ("Failure: %s: errno set to %d, expected %d (%s)\n",
631 test_name, errno_value, expected_value, expected_name);
632 }
633 ++noErrnoTests;
634 }
635
636 /* Test whether errno (value ERRNO_VALUE) has been for TEST_NAME set
637 as required by EXCEPTIONS. */
638 static void
639 test_errno (const char *test_name, int errno_value, int exceptions)
640 {
641 if (flag_test_errno)
642 {
643 int ran = 0;
644
645 if ((exceptions & (ERRNO_UNCHANGED|ERRNO_EDOM|ERRNO_ERANGE)) == 0)
646 {
647 if (print_screen (1))
648 printf ("Info: %s: The value of errno was not tested\n",
649 test_name);
650 return;
651 }
652
653
654 if (exceptions & ERRNO_UNCHANGED)
655 {
656 test_single_errno (test_name, errno_value, 0, "unchanged");
657 ran = 1;
658 }
659 if (exceptions & ERRNO_EDOM)
660 {
661 test_single_errno (test_name, errno_value, EDOM, "EDOM");
662 ran = 1;
663 }
664 if (exceptions & ERRNO_ERANGE)
665 {
666 test_single_errno (test_name, errno_value, ERANGE, "ERANGE");
667 ran = 1;
668 }
669
670 assert (ran == 1);
671 }
672 else
673 {
674 if (print_screen (1))
675 printf ("Info: %s: No errno tests\n", test_name);
676 }
677 }
678
679 /* Returns the number of ulps that GIVEN is away from EXPECTED. */
680 #define ULPDIFF(given, expected) \
681 (FUNC(fabs) ((given) - (expected)) / ulp (expected))
682
683 /* Returns the size of an ulp for VALUE. */
684 static FLOAT
685 ulp (FLOAT value)
686 {
687 FLOAT ulp;
688
689 switch (fpclassify (value))
690 {
691 case FP_ZERO:
692 /* We compute the distance to the next FP which is the same as the
693 value of the smallest subnormal number. Previously we used
694 2^-(MANT_DIG - 1) which is too large a value to be useful. Note that we
695 can't use ilogb(0), since that isn't a valid thing to do. As a point
696 of comparison Java's ulp returns the next normal value e.g.
697 2^(1 - MAX_EXP) for ulp(0), but that is not what we want for
698 glibc. */
699 /* Fall through... */
700 case FP_SUBNORMAL:
701 /* The next closest subnormal value is a constant distance away. */
702 ulp = FUNC(ldexp) (1.0, MIN_EXP - MANT_DIG);
703 break;
704
705 case FP_NORMAL:
706 ulp = FUNC(ldexp) (1.0, FUNC(ilogb) (value) - MANT_DIG + 1);
707 break;
708
709 default:
710 /* It should never happen. */
711 abort ();
712 break;
713 }
714 return ulp;
715 }
716
717 static void
718 check_float_internal (const char *test_name, FLOAT computed, FLOAT expected,
719 int exceptions,
720 FLOAT *curr_max_error, FLOAT max_ulp)
721 {
722 int ok = 0;
723 int print_diff = 0;
724 FLOAT diff = 0;
725 FLOAT ulps = 0;
726 int errno_value = errno;
727 int thisTest = noTests;
728
729 print_test_start (thisTest, test_name, TEST_INPUT);
730
731 test_exceptions (test_name, exceptions);
732 test_errno (test_name, errno_value, exceptions);
733 if (exceptions & IGNORE_RESULT)
734 goto out;
735 if (issignaling (computed) && issignaling (expected))
736 {
737 if ((exceptions & TEST_NAN_SIGN) != 0
738 && signbit (computed) != signbit (expected))
739 {
740 ok = 0;
741 printf ("signaling NaN has wrong sign.\n");
742 }
743 else if ((exceptions & TEST_NAN_PAYLOAD) != 0
744 && (FUNC (getpayload) (&computed)
745 != FUNC (getpayload) (&expected)))
746 {
747 ok = 0;
748 printf ("signaling NaN has wrong payload.\n");
749 }
750 else
751 ok = 1;
752 }
753 else if (issignaling (computed) || issignaling (expected))
754 ok = 0;
755 else if (isnan (computed) && isnan (expected))
756 {
757 if ((exceptions & TEST_NAN_SIGN) != 0
758 && signbit (computed) != signbit (expected))
759 {
760 ok = 0;
761 printf ("quiet NaN has wrong sign.\n");
762 }
763 else if ((exceptions & TEST_NAN_PAYLOAD) != 0
764 && (FUNC (getpayload) (&computed)
765 != FUNC (getpayload) (&expected)))
766 {
767 ok = 0;
768 printf ("quiet NaN has wrong payload.\n");
769 }
770 else
771 ok = 1;
772 }
773 else if (isinf (computed) && isinf (expected))
774 {
775 /* Test for sign of infinities. */
776 if ((exceptions & IGNORE_ZERO_INF_SIGN) == 0
777 && signbit (computed) != signbit (expected))
778 {
779 ok = 0;
780 printf ("infinity has wrong sign.\n");
781 }
782 else
783 ok = 1;
784 }
785 /* Don't calculate ULPs for infinities or any kind of NaNs. */
786 else if (isinf (computed) || isnan (computed)
787 || isinf (expected) || isnan (expected))
788 ok = 0;
789 else
790 {
791 diff = FUNC(fabs) (computed - expected);
792 ulps = ULPDIFF (computed, expected);
793 set_max_error (ulps, curr_max_error);
794 print_diff = 1;
795 if (((exceptions & IGNORE_ZERO_INF_SIGN) == 0) && !flag_test_mathvec
796 && computed == 0.0 && expected == 0.0
797 && signbit(computed) != signbit (expected))
798 ok = 0;
799 else if (ulps <= max_ulp && !ignore_max_ulp)
800 ok = 1;
801 else
802 ok = 0;
803 }
804 if (print_screen (ok))
805 {
806 if (!ok)
807 printf ("Failure: ");
808 printf ("Test: %s\n", test_name);
809 printf ("Result:\n");
810 printf (" is: ");
811 print_float (computed);
812 printf (" should be: ");
813 print_float (expected);
814 if (print_diff)
815 {
816 char dstrn[FSTR_MAX], dstrx[FSTR_MAX];
817 char ustrn[FSTR_MAX], mustrn[FSTR_MAX];
818 fmt_ftostr (dstrn, FSTR_MAX, TYPE_DECIMAL_DIG - 1, "e", diff);
819 fmt_ftostr (dstrx, FSTR_MAX, TYPE_HEX_DIG - 1, "a", diff);
820 fmt_ftostr (ustrn, FSTR_MAX, 4, "f", ulps);
821 fmt_ftostr (mustrn, FSTR_MAX, 4, "f", max_ulp);
822 printf (" difference: %s %s\n", dstrn, dstrx);
823 printf (" ulp : %s\n", ustrn);
824 printf (" max.ulp : %s\n", mustrn);
825 }
826 }
827 update_stats (ok, TEST_INPUT);
828
829 out:
830 fpstack_test (test_name);
831 feclearexcept (FE_ALL_EXCEPT);
832 errno = 0;
833 print_test_end (thisTest, test_name, TEST_INPUT);
834 }
835
836
837 void
838 check_float (const char *test_name, FLOAT computed, FLOAT expected,
839 int exceptions)
840 {
841 check_float_internal (test_name, computed, expected,
842 exceptions, &max_error, prev_max_error);
843 }
844
845
846 void
847 check_complex (const char *test_name, CFLOAT computed,
848 CFLOAT expected,
849 int exception)
850 {
851 FLOAT part_comp, part_exp;
852 char *str;
853
854 if (asprintf (&str, "Real part of: %s", test_name) == -1)
855 abort ();
856
857 part_comp = __real__ computed;
858 part_exp = __real__ expected;
859
860 check_float_internal (str, part_comp, part_exp,
861 exception, &real_max_error, prev_real_max_error);
862 free (str);
863
864 if (asprintf (&str, "Imaginary part of: %s", test_name) == -1)
865 abort ();
866
867 part_comp = __imag__ computed;
868 part_exp = __imag__ expected;
869
870 /* Don't check again for exceptions or errno, just pass through the
871 other relevant flags. */
872 check_float_internal (str, part_comp, part_exp,
873 exception & (IGNORE_ZERO_INF_SIGN
874 | TEST_NAN_SIGN
875 | IGNORE_RESULT),
876 &imag_max_error, prev_imag_max_error);
877 free (str);
878 }
879
880
881 /* Check that computed and expected values are equal (int values). */
882 void
883 check_int (const char *test_name, int computed, int expected,
884 int exceptions)
885 {
886 int ok = 0;
887 int errno_value = errno;
888 int thisTest = noTests;
889
890 print_test_start (thisTest, test_name, TEST_INPUT);
891
892 test_exceptions (test_name, exceptions);
893 test_errno (test_name, errno_value, exceptions);
894 if (exceptions & IGNORE_RESULT)
895 goto out;
896 if (computed == expected)
897 ok = 1;
898
899 if (print_screen (ok))
900 {
901 if (!ok)
902 printf ("Failure: ");
903 printf ("Test: %s\n", test_name);
904 printf ("Result:\n");
905 printf (" is: %d\n", computed);
906 printf (" should be: %d\n", expected);
907 }
908
909 update_stats (ok, TEST_INPUT);
910 out:
911 fpstack_test (test_name);
912 feclearexcept (FE_ALL_EXCEPT);
913 errno = 0;
914 print_test_end (thisTest, test_name, TEST_INPUT);
915 }
916
917
918 /* Check that computed and expected values are equal (long int values). */
919 void
920 check_long (const char *test_name, long int computed, long int expected,
921 int exceptions)
922 {
923 int ok = 0;
924 int errno_value = errno;
925 int thisTest = noTests;
926
927 print_test_start (thisTest, test_name, TEST_INPUT);
928
929 test_exceptions (test_name, exceptions);
930 test_errno (test_name, errno_value, exceptions);
931 if (exceptions & IGNORE_RESULT)
932 goto out;
933 if (computed == expected)
934 ok = 1;
935
936 if (print_screen (ok))
937 {
938 if (!ok)
939 printf ("Failure: ");
940 printf ("Test: %s\n", test_name);
941 printf ("Result:\n");
942 printf (" is: %ld\n", computed);
943 printf (" should be: %ld\n", expected);
944 }
945
946 update_stats (ok, TEST_INPUT);
947 out:
948 fpstack_test (test_name);
949 feclearexcept (FE_ALL_EXCEPT);
950 errno = 0;
951 print_test_end (thisTest, test_name, TEST_INPUT);
952 }
953
954
955 /* Check that computed value is true/false. */
956 void
957 check_bool (const char *test_name, int computed, int expected,
958 int exceptions)
959 {
960 int ok = 0;
961 int errno_value = errno;
962 int thisTest = noTests;
963
964 print_test_start (thisTest, test_name, TEST_INPUT);
965
966 test_exceptions (test_name, exceptions);
967 test_errno (test_name, errno_value, exceptions);
968 if (exceptions & IGNORE_RESULT)
969 goto out;
970 if ((computed == 0) == (expected == 0))
971 ok = 1;
972
973 if (print_screen (ok))
974 {
975 if (!ok)
976 printf ("Failure: ");
977 printf ("Test: %s\n", test_name);
978 printf ("Result:\n");
979 printf (" is: %d\n", computed);
980 printf (" should be: %d\n", expected);
981 }
982
983 update_stats (ok, TEST_INPUT);
984 out:
985 fpstack_test (test_name);
986 feclearexcept (FE_ALL_EXCEPT);
987 errno = 0;
988 print_test_end (thisTest, test_name, TEST_INPUT);
989 }
990
991
992 /* check that computed and expected values are equal (long int values) */
993 void
994 check_longlong (const char *test_name, long long int computed,
995 long long int expected,
996 int exceptions)
997 {
998 int ok = 0;
999 int errno_value = errno;
1000 int thisTest = noTests;
1001
1002 print_test_start (thisTest, test_name, TEST_INPUT);
1003
1004 test_exceptions (test_name, exceptions);
1005 test_errno (test_name, errno_value, exceptions);
1006 if (exceptions & IGNORE_RESULT)
1007 goto out;
1008 if (computed == expected)
1009 ok = 1;
1010
1011 if (print_screen (ok))
1012 {
1013 if (!ok)
1014 printf ("Failure:");
1015 printf ("Test: %s\n", test_name);
1016 printf ("Result:\n");
1017 printf (" is: %lld\n", computed);
1018 printf (" should be: %lld\n", expected);
1019 }
1020
1021 update_stats (ok, TEST_INPUT);
1022 out:
1023 fpstack_test (test_name);
1024 feclearexcept (FE_ALL_EXCEPT);
1025 errno = 0;
1026 print_test_end (thisTest, test_name, TEST_INPUT);
1027 }
1028
1029
1030 /* Check that computed and expected values are equal (intmax_t values). */
1031 void
1032 check_intmax_t (const char *test_name, intmax_t computed,
1033 intmax_t expected, int exceptions)
1034 {
1035 int ok = 0;
1036 int errno_value = errno;
1037 int thisTest = noTests;
1038
1039 print_test_start (thisTest, test_name, TEST_INPUT);
1040
1041 test_exceptions (test_name, exceptions);
1042 test_errno (test_name, errno_value, exceptions);
1043 if (exceptions & IGNORE_RESULT)
1044 goto out;
1045 if (computed == expected)
1046 ok = 1;
1047
1048 if (print_screen (ok))
1049 {
1050 if (!ok)
1051 printf ("Failure:");
1052 printf ("Test: %s\n", test_name);
1053 printf ("Result:\n");
1054 printf (" is: %jd\n", computed);
1055 printf (" should be: %jd\n", expected);
1056 }
1057
1058 update_stats (ok, TEST_INPUT);
1059 out:
1060 fpstack_test (test_name);
1061 feclearexcept (FE_ALL_EXCEPT);
1062 errno = 0;
1063 print_test_end (thisTest, test_name, TEST_INPUT);
1064 }
1065
1066
1067 /* Check that computed and expected values are equal (uintmax_t values). */
1068 void
1069 check_uintmax_t (const char *test_name, uintmax_t computed,
1070 uintmax_t expected, int exceptions)
1071 {
1072 int ok = 0;
1073 int errno_value = errno;
1074 int thisTest = noTests;
1075
1076 print_test_start (thisTest, test_name, TEST_INPUT);
1077
1078 test_exceptions (test_name, exceptions);
1079 test_errno (test_name, errno_value, exceptions);
1080 if (exceptions & IGNORE_RESULT)
1081 goto out;
1082 if (computed == expected)
1083 ok = 1;
1084
1085 if (print_screen (ok))
1086 {
1087 if (!ok)
1088 printf ("Failure:");
1089 printf ("Test: %s\n", test_name);
1090 printf ("Result:\n");
1091 printf (" is: %ju\n", computed);
1092 printf (" should be: %ju\n", expected);
1093 }
1094
1095 update_stats (ok, TEST_INPUT);
1096 out:
1097 fpstack_test (test_name);
1098 feclearexcept (FE_ALL_EXCEPT);
1099 errno = 0;
1100 print_test_end (thisTest, test_name, TEST_INPUT);
1101 }
1102
1103 /* Return whether a test with flags EXCEPTIONS should be run. */
1104 int
1105 enable_test (int exceptions)
1106 {
1107 if (exceptions & XFAIL_TEST)
1108 return 0;
1109 if ((!SNAN_TESTS (FLOAT) || !snan_tests_arg)
1110 && (exceptions & TEST_SNAN) != 0)
1111 return 0;
1112 if (flag_test_mathvec && (exceptions & NO_TEST_MATHVEC) != 0)
1113 return 0;
1114
1115 return 1;
1116 }
1117
1118 static void
1119 initialize (void)
1120 {
1121 fpstack_test ("start *init*");
1122
1123 /* Clear all exceptions. From now on we must not get random exceptions. */
1124 feclearexcept (FE_ALL_EXCEPT);
1125 errno = 0;
1126
1127 /* Test to make sure we start correctly. */
1128 fpstack_test ("end *init*");
1129 }
1130
1131 /* Definitions of arguments for argp functions. */
1132 static const struct argp_option options[] =
1133 {
1134 { "verbose", 'v', "NUMBER", 0, "Level of verbosity (0..3)"},
1135 { "ulps-file", 'u', NULL, 0, "Output ulps to file ULPs"},
1136 { "no-max-error", 'f', NULL, 0,
1137 "Don't output maximal errors of functions"},
1138 { "no-points", 'p', NULL, 0,
1139 "Don't output results of functions invocations"},
1140 { "ignore-max-ulp", 'i', "yes/no", 0,
1141 "Ignore given maximal errors"},
1142 { "output-dir", 'o', "DIR", 0,
1143 "Directory where generated files will be placed"},
1144 { NULL, 0, NULL, 0, NULL }
1145 };
1146
1147 /* Prototype for option handler. */
1148 static error_t parse_opt (int key, char *arg, struct argp_state *state);
1149
1150 /* Data structure to communicate with argp functions. */
1151 static struct argp argp =
1152 {
1153 options, parse_opt, NULL, doc,
1154 };
1155
1156
1157 /* Handle program arguments. */
1158 static error_t
1159 parse_opt (int key, char *arg, struct argp_state *state)
1160 {
1161 switch (key)
1162 {
1163 case 'f':
1164 output_max_error = 0;
1165 break;
1166 case 'i':
1167 if (strcmp (arg, "yes") == 0)
1168 ignore_max_ulp = 1;
1169 else if (strcmp (arg, "no") == 0)
1170 ignore_max_ulp = 0;
1171 break;
1172 case 'o':
1173 output_dir = (char *) malloc (strlen (arg) + 1);
1174 if (output_dir != NULL)
1175 strcpy (output_dir, arg);
1176 else
1177 return errno;
1178 break;
1179 case 'p':
1180 output_points = 0;
1181 break;
1182 case 'u':
1183 output_ulps = 1;
1184 break;
1185 case 'v':
1186 if (optarg)
1187 {
1188 char *optstr_conv = optarg;
1189 unsigned int opt_verbose;
1190
1191 opt_verbose = (unsigned int) strtoul (optarg, &optstr_conv, 0);
1192 if (*optstr_conv == '\0' && optstr_conv != optarg)
1193 verbose = opt_verbose;
1194 }
1195 else
1196 verbose = 3;
1197 break;
1198 default:
1199 return ARGP_ERR_UNKNOWN;
1200 }
1201 return 0;
1202 }
1203
1204 /* Verify that our ulp () implementation is behaving as expected
1205 or abort. */
1206 static void
1207 check_ulp (void)
1208 {
1209 FLOAT ulps, ulpx, value;
1210 int i;
1211 /* Check ulp of zero is a subnormal value... */
1212 ulps = ulp (0x0.0p0);
1213 if (fpclassify (ulps) != FP_SUBNORMAL)
1214 {
1215 fprintf (stderr, "ulp (0x0.0p0) is not FP_SUBNORMAL!\n");
1216 exit (EXIT_FAILURE);
1217 }
1218 /* Check that the ulp of one is a normal value... */
1219 ulps = ulp (LIT(1.0));
1220 if (fpclassify (ulps) != FP_NORMAL)
1221 {
1222 fprintf (stderr, "ulp (1.0L) is not FP_NORMAL\n");
1223 exit (EXIT_FAILURE);
1224 }
1225
1226 /* Compute the next subnormal value using nextafter to validate ulp.
1227 We allow +/- 1 ulp around the represented value. */
1228 value = FUNC(nextafter) (0, 1);
1229 ulps = ULPDIFF (value, 0);
1230 ulpx = ulp (LIT(1.0));
1231 if (ulps < (LIT(1.0) - ulpx) || ulps > (LIT(1.0) + ulpx))
1232 {
1233 fprintf (stderr, "Value outside of 1 +/- 1ulp.\n");
1234 exit (EXIT_FAILURE);
1235 }
1236 /* Compute the nearest representable number from 10 towards 20.
1237 The result is 10 + 1ulp. We use this to check the ulp function.
1238 We allow +/- 1 ulp around the represented value. */
1239 value = FUNC(nextafter) (10, 20);
1240 ulps = ULPDIFF (value, 10);
1241 ulpx = ulp (LIT(1.0));
1242 if (ulps < (LIT(1.0) - ulpx) || ulps > (LIT(1.0) + ulpx))
1243 {
1244 fprintf (stderr, "Value outside of 1 +/- 1ulp.\n");
1245 exit (EXIT_FAILURE);
1246 }
1247 /* This gives one more ulp. */
1248 value = FUNC(nextafter) (value, 20);
1249 ulps = ULPDIFF (value, 10);
1250 ulpx = ulp (LIT(2.0));
1251 if (ulps < (LIT(2.0) - ulpx) || ulps > (LIT(2.0) + ulpx))
1252 {
1253 fprintf (stderr, "Value outside of 2 +/- 1ulp.\n");
1254 exit (EXIT_FAILURE);
1255 }
1256 /* And now calculate 100 ulp. */
1257 for (i = 2; i < 100; i++)
1258 value = FUNC(nextafter) (value, 20);
1259 ulps = ULPDIFF (value, 10);
1260 ulpx = ulp (LIT(100.0));
1261 if (ulps < (LIT(100.0) - ulpx) || ulps > (LIT(100.0) + ulpx))
1262 {
1263 fprintf (stderr, "Value outside of 100 +/- 1ulp.\n");
1264 exit (EXIT_FAILURE);
1265 }
1266 }
1267
1268 /* Do all initialization for a test run with arguments given by ARGC
1269 and ARGV. */
1270 void
1271 libm_test_init (int argc, char **argv)
1272 {
1273 int remaining;
1274 char *ulps_file_path;
1275 size_t dir_len = 0;
1276 char *envstr_verbose;
1277
1278 verbose = 1;
1279 output_ulps = 0;
1280 output_max_error = 1;
1281 output_points = 1;
1282 output_dir = NULL;
1283 /* XXX set to 0 for releases. */
1284 ignore_max_ulp = 0;
1285
1286 envstr_verbose = getenv("GLIBC_TEST_LIBM_VERBOSE");
1287 if (envstr_verbose != NULL)
1288 {
1289 char *envstr_conv = envstr_verbose;
1290 unsigned int env_verbose;
1291
1292 env_verbose = (unsigned int) strtoul (envstr_verbose, &envstr_conv, 0);
1293 if (*envstr_conv == '\0' && envstr_conv != envstr_verbose)
1294 verbose = env_verbose;
1295 }
1296
1297 /* Parse and process arguments. */
1298 argp_parse (&argp, argc, argv, 0, &remaining, NULL);
1299
1300 if (remaining != argc)
1301 {
1302 fprintf (stderr, "wrong number of arguments");
1303 argp_help (&argp, stdout, ARGP_HELP_SEE, program_invocation_short_name);
1304 exit (EXIT_FAILURE);
1305 }
1306
1307 if (output_ulps)
1308 {
1309 if (output_dir != NULL)
1310 dir_len = strlen (output_dir);
1311 ulps_file_path = (char *) malloc (dir_len + strlen (ulps_file_name) + 1);
1312 if (ulps_file_path == NULL)
1313 {
1314 perror ("can't allocate path for `ULPs' file: ");
1315 exit (1);
1316 }
1317 sprintf (ulps_file_path, "%s%s", output_dir == NULL ? "" : output_dir, ulps_file_name);
1318 ulps_file = fopen (ulps_file_path, "a");
1319 if (ulps_file == NULL)
1320 {
1321 perror ("can't open file `ULPs' for writing: ");
1322 exit (1);
1323 }
1324 }
1325
1326
1327 initialize ();
1328 fputs (test_msg, stdout);
1329
1330 check_ulp ();
1331 }
1332
1333 /* Process the test results, returning the exit status. */
1334 int
1335 libm_test_finish (void)
1336 {
1337 if (output_ulps)
1338 fclose (ulps_file);
1339
1340 printf ("\nTest suite completed:\n");
1341 printf (" Maximum error found of ");
1342 if (is_complex)
1343 {
1344 char rmestr[FSTR_MAX];
1345 char imestr[FSTR_MAX];
1346 FTOSTR (rmestr, FSTR_MAX, "%.0f", FUNC (ceil) (real_max_error));
1347 FTOSTR (imestr, FSTR_MAX, "%.0f", FUNC (ceil) (imag_max_error));
1348 printf ("`%s' ulp for real part and `%s' ulp for imaginary part\n",
1349 rmestr, imestr);
1350 }
1351 else
1352 {
1353 char mestr[FSTR_MAX];
1354 FTOSTR (mestr, FSTR_MAX, "%.0f", FUNC (ceil) (max_error));
1355 printf ("`%s' ulp\n", mestr);
1356 }
1357 printf (" %d max error test cases,\n", noMaxErrorTests);
1358 printf (" %d input tests,\n", noTests);
1359 printf (" - with %d tests for exception flags,\n", noExcTests);
1360 printf (" - with %d tests for errno executed.\n", noErrnoTests);
1361
1362 if (noErrors)
1363 {
1364 printf (" %d errors occurred.\n", noErrors);
1365 return 1;
1366 }
1367 printf (" All tests passed successfully.\n");
1368
1369 return 0;
1370 }