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