diff options
Diffstat (limited to 'math')
-rw-r--r-- | math/libm-test.inc | 209 | ||||
-rw-r--r-- | math/test-double.h | 4 | ||||
-rw-r--r-- | math/test-float.h | 4 | ||||
-rw-r--r-- | math/test-ldouble.h | 4 |
4 files changed, 127 insertions, 94 deletions
diff --git a/math/libm-test.inc b/math/libm-test.inc index 84104b4a58..6dddf7cf44 100644 --- a/math/libm-test.inc +++ b/math/libm-test.inc @@ -34,7 +34,13 @@ the specifier, not the percent and width arguments, e.g. "f". PRINTF_XEXPR Like PRINTF_EXPR, but print in hexadecimal format. - PRINTF_NEXPR Like PRINTF_EXPR, but print nice. */ + PRINTF_NEXPR Like PRINTF_EXPR, but print nice. + PREFIX A macro which defines the prefix for common macros for the + type (i.e LDBL, DBL, or FLT). + LIT A function which appends the correct suffix to a literal. + TYPE_STR A macro which defines a stringitized name of the type. + FTOSTR This macro defines a function similar in type to snprintf + which converts a FLOAT to a string. */ /* This testsuite has currently tests for: acos, acosh, asin, asinh, atan, atan2, atanh, @@ -183,31 +189,74 @@ struct ulp_data #define NON_FINITE 0x40000 #define TEST_SNAN 0x80000 +#define __CONCATX(a,b) __CONCAT(a,b) + +#define TYPE_MIN __CONCATX (PREFIX, _MIN) +#define TYPE_TRUE_MIN __CONCATX (PREFIX, _TRUE_MIN) +#define TYPE_MAX __CONCATX (PREFIX, _MAX) +#define MIN_EXP __CONCATX (PREFIX, _MIN_EXP) +#define MAX_EXP __CONCATX (PREFIX, _MAX_EXP) +#define MANT_DIG __CONCATX (PREFIX, _MANT_DIG) + +/* Maximum character buffer to store a stringitized FLOAT value. */ +#define FSTR_MAX (128) + +#if TEST_INLINE +# define QTYPE_STR "i" TYPE_STR +#else +# define QTYPE_STR TYPE_STR +#endif + +/* Format specific test macros. */ +#define TEST_COND_binary32 (MANT_DIG == 24 \ + && MIN_EXP == -125 \ + && MAX_EXP == 128) + +#define TEST_COND_binary64 (MANT_DIG == 53 \ + && MIN_EXP == -1021 \ + && MAX_EXP == 1024) + +#define TEST_COND_binary128 (MANT_DIG == 113 \ + && MIN_EXP == -16381 \ + && MAX_EXP == 16384) + +#define TEST_COND_ibm128 (MANT_DIG == 106) + +#define TEST_COND_intel96 (MANT_DIG == 64 \ + && MIN_EXP == -16381 \ + && MAX_EXP == 16384) + +#define TEST_COND_m68k96 (MANT_DIG == 64 \ + && MIN_EXP == -16382 \ + && MAX_EXP == 16384) + /* Values underflowing only for float. */ -#ifdef TEST_FLOAT +#if TEST_COND_binary32 # define UNDERFLOW_EXCEPTION_FLOAT UNDERFLOW_EXCEPTION # define UNDERFLOW_EXCEPTION_OK_FLOAT UNDERFLOW_EXCEPTION_OK #else # define UNDERFLOW_EXCEPTION_FLOAT 0 # define UNDERFLOW_EXCEPTION_OK_FLOAT 0 #endif + /* Values underflowing only for double or types with a larger least positive normal value. */ -#if defined TEST_FLOAT || defined TEST_DOUBLE \ - || (defined TEST_LDOUBLE && LDBL_MIN_EXP >= DBL_MIN_EXP) +#if TEST_COND_binary32 || TEST_COND_binary64 || TEST_COND_ibm128 # define UNDERFLOW_EXCEPTION_DOUBLE UNDERFLOW_EXCEPTION # define UNDERFLOW_EXCEPTION_OK_DOUBLE UNDERFLOW_EXCEPTION_OK #else # define UNDERFLOW_EXCEPTION_DOUBLE 0 # define UNDERFLOW_EXCEPTION_OK_DOUBLE 0 #endif + /* Values underflowing only for IBM long double or types with a larger least positive normal value. */ -#if defined TEST_FLOAT || (defined TEST_LDOUBLE && LDBL_MIN_EXP > DBL_MIN_EXP) +#if TEST_COND_binary32 || TEST_COND_ibm128 # define UNDERFLOW_EXCEPTION_LDOUBLE_IBM UNDERFLOW_EXCEPTION #else # define UNDERFLOW_EXCEPTION_LDOUBLE_IBM 0 #endif + /* Values underflowing on architectures detecting tininess before rounding, but not on those detecting tininess after rounding. */ #define UNDERFLOW_EXCEPTION_BEFORE_ROUNDING (TININESS_AFTER_ROUNDING \ @@ -227,36 +276,13 @@ struct ulp_data #endif /* Conditions used by tests generated by gen-auto-libm-tests.c. */ -#ifdef TEST_FLOAT -# define TEST_COND_flt_32 1 -#else -# define TEST_COND_flt_32 0 -#endif -#if defined TEST_DOUBLE || (defined TEST_LDOUBLE && LDBL_MANT_DIG == 53) -# define TEST_COND_dbl_64 1 -#else -# define TEST_COND_dbl_64 0 -#endif -#if defined TEST_LDOUBLE && LDBL_MANT_DIG == 64 && LDBL_MIN_EXP == -16381 -# define TEST_COND_ldbl_96_intel 1 -#else -# define TEST_COND_ldbl_96_intel 0 -#endif -#if defined TEST_LDOUBLE && LDBL_MANT_DIG == 64 && LDBL_MIN_EXP == -16382 -# define TEST_COND_ldbl_96_m68k 1 -#else -# define TEST_COND_ldbl_96_m68k 0 -#endif -#if defined TEST_LDOUBLE && LDBL_MANT_DIG == 113 -# define TEST_COND_ldbl_128 1 -#else -# define TEST_COND_ldbl_128 0 -#endif -#if defined TEST_LDOUBLE && LDBL_MANT_DIG == 106 -# define TEST_COND_ldbl_128ibm 1 -#else -# define TEST_COND_ldbl_128ibm 0 -#endif +#define TEST_COND_flt_32 TEST_COND_binary32 +#define TEST_COND_dbl_64 TEST_COND_binary64 +#define TEST_COND_ldbl_96_intel TEST_COND_intel96 +#define TEST_COND_ldbl_96_m68k TEST_COND_m68k96 +#define TEST_COND_ldbl_128 TEST_COND_binary128 +#define TEST_COND_ldbl_128ibm TEST_COND_ibm128 + #if LONG_MAX == 0x7fffffff # define TEST_COND_long32 1 # define TEST_COND_long64 0 @@ -302,26 +328,15 @@ static int output_max_error; /* Should the maximal errors printed? */ static int output_points; /* Should the single function results printed? */ static int ignore_max_ulp; /* Should we ignore max_ulp? */ -#define plus_zero CHOOSE (0.0L, 0.0, 0.0f, \ - 0.0L, 0.0, 0.0f) -#define minus_zero CHOOSE (-0.0L, -0.0, -0.0f, \ - -0.0L, -0.0, -0.0f) -#define plus_infty CHOOSE (HUGE_VALL, HUGE_VAL, HUGE_VALF, \ - HUGE_VALL, HUGE_VAL, HUGE_VALF) -#define minus_infty CHOOSE (-HUGE_VALL, -HUGE_VAL, -HUGE_VALF, \ - -HUGE_VALL, -HUGE_VAL, -HUGE_VALF) +#define plus_zero LIT (0.0) +#define minus_zero LIT (-0.0) +#define plus_infty FUNC (__builtin_inf) () +#define minus_infty -(FUNC (__builtin_inf) ()) #define qnan_value FUNC (__builtin_nan) ("") #define snan_value FUNC (__builtin_nans) ("") -#define max_value CHOOSE (LDBL_MAX, DBL_MAX, FLT_MAX, \ - LDBL_MAX, DBL_MAX, FLT_MAX) -#define min_value CHOOSE (LDBL_MIN, DBL_MIN, FLT_MIN, \ - LDBL_MIN, DBL_MIN, FLT_MIN) -#define min_subnorm_value CHOOSE (LDBL_TRUE_MIN, \ - DBL_TRUE_MIN, \ - FLT_TRUE_MIN, \ - LDBL_TRUE_MIN, \ - DBL_TRUE_MIN, \ - FLT_TRUE_MIN) +#define max_value TYPE_MAX +#define min_value TYPE_MIN +#define min_subnorm_value TYPE_TRUE_MIN static FLOAT max_error, real_max_error, imag_max_error; @@ -329,23 +344,12 @@ static FLOAT prev_max_error, prev_real_max_error, prev_imag_max_error; static FLOAT max_valid_error; -#define MANT_DIG CHOOSE (LDBL_MANT_DIG, DBL_MANT_DIG, FLT_MANT_DIG, \ - LDBL_MANT_DIG, DBL_MANT_DIG, FLT_MANT_DIG) -#define MIN_EXP CHOOSE (LDBL_MIN_EXP, DBL_MIN_EXP, FLT_MIN_EXP, \ - LDBL_MIN_EXP, DBL_MIN_EXP, FLT_MIN_EXP) -#define MAX_EXP CHOOSE (LDBL_MAX_EXP, DBL_MAX_EXP, FLT_MAX_EXP, \ - LDBL_MAX_EXP, DBL_MAX_EXP, FLT_MAX_EXP) /* Sufficient numbers of digits to represent any floating-point value unambiguously (for any choice of the number of bits in the first hex digit, in the case of TYPE_HEX_DIG). When used with printf formats where the precision counts only digits after the point, 1 is subtracted from these values. */ -#define TYPE_DECIMAL_DIG CHOOSE (LDBL_DECIMAL_DIG, \ - DBL_DECIMAL_DIG, \ - FLT_DECIMAL_DIG, \ - LDBL_DECIMAL_DIG, \ - DBL_DECIMAL_DIG, \ - FLT_DECIMAL_DIG) +#define TYPE_DECIMAL_DIG __CONCATX (PREFIX, _DECIMAL_DIG) #define TYPE_HEX_DIG ((MANT_DIG + 6) / 4) /* Compare KEY (a string, with the name of a function) with ULP (a @@ -428,8 +432,12 @@ print_float (FLOAT f) else if (isnan (f)) printf ("qNaN\n"); else - printf ("% .*" PRINTF_EXPR " % .*" PRINTF_XEXPR "\n", - TYPE_DECIMAL_DIG - 1, f, TYPE_HEX_DIG - 1, f); + { + char fstrn[FSTR_MAX], fstrx[FSTR_MAX]; + FTOSTR (fstrn, FSTR_MAX, "% .*" PRINTF_EXPR, TYPE_DECIMAL_DIG - 1, f); + FTOSTR (fstrx, FSTR_MAX, "% .*" PRINTF_XEXPR, TYPE_HEX_DIG - 1, f); + printf ("%s %s\n", fstrn, fstrx); + } } /* Should the message print to screen? This depends on the verbose flag, @@ -471,11 +479,10 @@ print_function_ulps (const char *function_name, FLOAT ulp) { if (output_ulps) { + char ustrn[FSTR_MAX]; + FTOSTR (ustrn, FSTR_MAX, "%.0" PRINTF_NEXPR, FUNC (ceil) (ulp)); fprintf (ulps_file, "Function: \"%s\":\n", function_name); - fprintf (ulps_file, "%s: %.0" PRINTF_NEXPR "\n", - CHOOSE("ldouble", "double", "float", - "ildouble", "idouble", "ifloat"), - FUNC(ceil) (ulp)); + fprintf (ulps_file, QTYPE_STR ": %s\n", ustrn); } } @@ -486,21 +493,20 @@ print_complex_function_ulps (const char *function_name, FLOAT real_ulp, { if (output_ulps) { + char fstrn[FSTR_MAX]; if (real_ulp != 0.0) { + FTOSTR (fstrn, FSTR_MAX, "%.0" PRINTF_NEXPR, + FUNC (ceil) (real_ulp)); fprintf (ulps_file, "Function: Real part of \"%s\":\n", function_name); - fprintf (ulps_file, "%s: %.0" PRINTF_NEXPR "\n", - CHOOSE("ldouble", "double", "float", - "ildouble", "idouble", "ifloat"), - FUNC(ceil) (real_ulp)); + fprintf (ulps_file, QTYPE_STR ": %s\n", fstrn); } if (imag_ulp != 0.0) { + FTOSTR (fstrn, FSTR_MAX, "%.0" PRINTF_NEXPR, + FUNC (ceil) (imag_ulp)); fprintf (ulps_file, "Function: Imaginary part of \"%s\":\n", function_name); - fprintf (ulps_file, "%s: %.0" PRINTF_NEXPR "\n", - CHOOSE("ldouble", "double", "float", - "ildouble", "idouble", "ifloat"), - FUNC(ceil) (imag_ulp)); + fprintf (ulps_file, QTYPE_STR ": %s\n", fstrn); } @@ -548,10 +554,12 @@ print_max_error (const char *func_name) if (print_screen_max_error (ok)) { + char mestr[FSTR_MAX], pmestr[FSTR_MAX]; + FTOSTR (mestr, FSTR_MAX, "%.0" PRINTF_NEXPR, FUNC (ceil) (max_error)); + FTOSTR (pmestr, FSTR_MAX, "%.0" PRINTF_NEXPR, FUNC (ceil) (prev_max_error)); printf ("Maximal error of `%s'\n", func_name); - printf (" is : %.0" PRINTF_NEXPR " ulp\n", FUNC(ceil) (max_error)); - printf (" accepted: %.0" PRINTF_NEXPR " ulp\n", - FUNC(ceil) (prev_max_error)); + printf (" is : %s ulp\n", mestr); + printf (" accepted: %s ulp\n", pmestr); } update_stats (ok); @@ -584,16 +592,22 @@ print_complex_max_error (const char *func_name) if (print_screen_max_error (ok)) { + char rmestr[FSTR_MAX], prmestr[FSTR_MAX]; + char imestr[FSTR_MAX], pimestr[FSTR_MAX]; + FTOSTR (rmestr, FSTR_MAX, "%.0" PRINTF_NEXPR, + FUNC (ceil) (real_max_error)); + FTOSTR (prmestr, FSTR_MAX, "%.0" PRINTF_NEXPR, + FUNC (ceil) (prev_real_max_error)); + FTOSTR (imestr, FSTR_MAX, "%.0" PRINTF_NEXPR, + FUNC (ceil) (imag_max_error)); + FTOSTR (pimestr, FSTR_MAX, "%.0" PRINTF_NEXPR, + FUNC (ceil) (prev_imag_max_error)); printf ("Maximal error of real part of: %s\n", func_name); - printf (" is : %.0" PRINTF_NEXPR " ulp\n", - FUNC(ceil) (real_max_error)); - printf (" accepted: %.0" PRINTF_NEXPR " ulp\n", - FUNC(ceil) (prev_real_max_error)); + printf (" is : %s ulp\n", rmestr); + printf (" accepted: %s ulp\n", prmestr); printf ("Maximal error of imaginary part of: %s\n", func_name); - printf (" is : %.0" PRINTF_NEXPR " ulp\n", - FUNC(ceil) (imag_max_error)); - printf (" accepted: %.0" PRINTF_NEXPR " ulp\n", - FUNC(ceil) (prev_imag_max_error)); + printf (" is : %s ulp\n", imestr); + printf (" accepted: %s ulp\n", pimestr); } update_stats (ok); @@ -851,10 +865,17 @@ check_float_internal (const char *test_name, FLOAT computed, FLOAT expected, print_float (expected); if (print_diff) { - printf (" difference: % .*" PRINTF_EXPR " % .*" PRINTF_XEXPR - "\n", TYPE_DECIMAL_DIG - 1, diff, TYPE_HEX_DIG - 1, diff); - printf (" ulp : % .4" PRINTF_NEXPR "\n", ulps); - printf (" max.ulp : % .4" PRINTF_NEXPR "\n", max_ulp); + char dstrn[FSTR_MAX], dstrx[FSTR_MAX]; + char ustrn[FSTR_MAX], mustrn[FSTR_MAX]; + FTOSTR (dstrn, FSTR_MAX, "% .*" PRINTF_EXPR, + TYPE_DECIMAL_DIG - 1, diff); + FTOSTR (dstrx, FSTR_MAX, "% .*" PRINTF_XEXPR, + TYPE_HEX_DIG - 1, diff); + FTOSTR (ustrn, FSTR_MAX, "% .4" PRINTF_NEXPR, ulps); + FTOSTR (mustrn, FSTR_MAX, "% .4" PRINTF_NEXPR, max_ulp); + printf (" difference: %s %s\n", dstrn, dstrx); + printf (" ulp : %s\n", ustrn); + printf (" max.ulp : %s\n", mustrn); } } update_stats (ok); diff --git a/math/test-double.h b/math/test-double.h index 16b4ce8081..6783b4449c 100644 --- a/math/test-double.h +++ b/math/test-double.h @@ -23,3 +23,7 @@ #define PRINTF_NEXPR "f" #define TEST_DOUBLE 1 #define BUILD_COMPLEX(real, imag) (CMPLX ((real), (imag))) +#define PREFIX DBL +#define LIT(x) (x) +#define TYPE_STR "double" +#define FTOSTR snprintf diff --git a/math/test-float.h b/math/test-float.h index 629f6ee68a..9bb3b84651 100644 --- a/math/test-float.h +++ b/math/test-float.h @@ -23,3 +23,7 @@ #define PRINTF_NEXPR "f" #define TEST_FLOAT 1 #define BUILD_COMPLEX(real, imag) (CMPLXF ((real), (imag))) +#define PREFIX FLT +#define TYPE_STR "float" +#define LIT(x) (x ## f) +#define FTOSTR snprintf diff --git a/math/test-ldouble.h b/math/test-ldouble.h index 481561f1e7..63f5008b95 100644 --- a/math/test-ldouble.h +++ b/math/test-ldouble.h @@ -23,3 +23,7 @@ #define PRINTF_NEXPR "Lf" #define TEST_LDOUBLE 1 #define BUILD_COMPLEX(real, imag) (CMPLXL ((real), (imag))) +#define PREFIX LDBL +#define TYPE_STR "ldouble" +#define LIT(x) (x ## L) +#define FTOSTR snprintf |