From patchwork Mon Dec 19 18:23:19 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gabriel F T Gomes X-Patchwork-Id: 18584 Received: (qmail 80922 invoked by alias); 19 Dec 2016 18:23:31 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 80884 invoked by uid 89); 19 Dec 2016 18:23:30 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-5.0 required=5.0 tests=BAYES_00, RP_MATCHES_RCVD, SPF_PASS autolearn=ham version=3.3.2 spammy=Real, HX-Envelope-From:sk:gabriel, sprintf, printfs X-HELO: mail.gftg.com.br From: "Gabriel F. T. Gomes" To: libc-alpha@sourceware.org Subject: [PATCH v2] Replace use of snprintf with strfrom in libm tests Date: Mon, 19 Dec 2016 16:23:19 -0200 Message-Id: <1482171799-3636-1-git-send-email-gftg@linux.vnet.ibm.com> Changes since v1: - Remove the macros PRINTF_EXPR, PRINTF_NEXPR, and PRINTF_XEXPR. - Use totalorder in fmt_ftostr to detect if the floating-point number being printed is non-negative, then add a leading space. Addition of the leading space depends on the new parameter 'space'. - Remove format from the parameters of fmt_ftostr, since strfrom accepts only a very limited subset of printf's format. Create the format string based on the parameters precision and conversion. ---8<--- In order to support float128 tests, the calls to snprintf, which does not support the type __float128, are replaced with calls to strfrom{f,d,l}. 2016-11-08 Gabriel F. T. Gomes * math/libm-test.inc (fmt_ftostr): New function. (print_float, check_float_internal): Replace some uses of FTOSTR with uses of fmt_ftostr. (print_max_error, print_complex_max_error, print_function_ulps) (print_complex_function_ulps): Remove uses of the macros PRINTF_EXPR, PRINTF_NEXPR, and PRINTF_XEXPR. * math/test-double.h (FTOSTR): Define to strfromd. (PRINTF_EXPR): Delete. (PRINTF_XEXPR): Likewise. (PRINTF_NEXPR): Likewise. * math/test-float.h (FTOSTR): Define to strfromf. (PRINTF_EXPR): Delete. (PRINTF_XEXPR): Likewise. (PRINTF_NEXPR): Likewise. * math/test-ldouble.h (FTOSTR): Define to strfroml. (PRINTF_EXPR): Delete. (PRINTF_XEXPR): Likewise. (PRINTF_NEXPR): Likewise. --- math/libm-test.inc | 79 +++++++++++++++++++++++++++++++++-------------------- math/test-double.h | 5 +--- math/test-float.h | 5 +--- math/test-ldouble.h | 5 +--- 4 files changed, 52 insertions(+), 42 deletions(-) diff --git a/math/libm-test.inc b/math/libm-test.inc index 110b421..668fd8b 100644 --- a/math/libm-test.inc +++ b/math/libm-test.inc @@ -28,17 +28,11 @@ - TEST_MSG: informal message to be displayed chooses one of the parameters as delta for testing equality - PRINTF_EXPR Floating point conversion specification to print a variable - of type FLOAT with printf. PRINTF_EXPR just contains - 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. 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 + FTOSTR This macro defines a function similar in type to strfromf which converts a FLOAT to a string. */ /* This testsuite has currently tests for: @@ -355,6 +349,39 @@ static FLOAT max_valid_error; #define TYPE_DECIMAL_DIG __CONCATX (PREFIX, _DECIMAL_DIG) #define TYPE_HEX_DIG ((MANT_DIG + 6) / 4) +/* Converts VALUE (a floating-point number) to string and writes it to DEST. + PRECISION specifies the number of fractional digits that should be printed. + CONVERSION is the conversion specifier, such as in printf, e.g. 'f' or 'a'. + The output is prepended with an empty space if VALUE is non-negative and if + SPACE is true. The function fmt_ftostr calls one of the strfrom functions + and returns the same code. */ +static int +fmt_ftostr (char *dest, size_t size, bool space, int precision, + const char *conversion, FLOAT value) +{ + char format[64]; + char *ptr_format; + int ret; + + /* Generate the format string. */ + ptr_format = stpcpy (format, "%."); + ret = sprintf (ptr_format, "%d", precision); + ptr_format += ret; + ptr_format = stpcpy (ptr_format, conversion); + + /* Add a space to the beginning of the output string, if the floating-point + number is non-negative. This mimics the behavior of the space (' ') flag + in snprintf, which is not available on strfrom. */ + if (space && FUNC (totalorder) (LIT (0.0), value)) + { + *dest = ' '; + dest++; + } + + /* Call the float to string conversion function, e.g.: strfromd. */ + return FTOSTR (dest, size, format, value); +} + /* Compare KEY (a string, with the name of a function) with ULP (a pointer to a struct ulp_data structure), returning a value less than, equal to or greater than zero for use in bsearch. */ @@ -437,8 +464,8 @@ print_float (FLOAT f) else { 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); + fmt_ftostr (fstrn, FSTR_MAX, 1, TYPE_DECIMAL_DIG - 1, "e", f); + fmt_ftostr (fstrx, FSTR_MAX, 1, TYPE_HEX_DIG - 1, "a", f); printf ("%s %s\n", fstrn, fstrx); } } @@ -483,7 +510,7 @@ 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)); + FTOSTR (ustrn, FSTR_MAX, "%.0f", FUNC (ceil) (ulp)); fprintf (ulps_file, "Function: \"%s\":\n", function_name); fprintf (ulps_file, QTYPE_STR ": %s\n", ustrn); } @@ -499,15 +526,13 @@ print_complex_function_ulps (const char *function_name, FLOAT real_ulp, char fstrn[FSTR_MAX]; if (real_ulp != 0.0) { - FTOSTR (fstrn, FSTR_MAX, "%.0" PRINTF_NEXPR, - FUNC (ceil) (real_ulp)); + FTOSTR (fstrn, FSTR_MAX, "%.0f", FUNC (ceil) (real_ulp)); fprintf (ulps_file, "Function: Real part of \"%s\":\n", function_name); fprintf (ulps_file, QTYPE_STR ": %s\n", fstrn); } if (imag_ulp != 0.0) { - FTOSTR (fstrn, FSTR_MAX, "%.0" PRINTF_NEXPR, - FUNC (ceil) (imag_ulp)); + FTOSTR (fstrn, FSTR_MAX, "%.0f", FUNC (ceil) (imag_ulp)); fprintf (ulps_file, "Function: Imaginary part of \"%s\":\n", function_name); fprintf (ulps_file, QTYPE_STR ": %s\n", fstrn); } @@ -558,8 +583,8 @@ 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)); + FTOSTR (mestr, FSTR_MAX, "%.0f", FUNC (ceil) (max_error)); + FTOSTR (pmestr, FSTR_MAX, "%.0f", FUNC (ceil) (prev_max_error)); printf ("Maximal error of `%s'\n", func_name); printf (" is : %s ulp\n", mestr); printf (" accepted: %s ulp\n", pmestr); @@ -597,14 +622,10 @@ print_complex_max_error (const char *func_name) { 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)); + FTOSTR (rmestr, FSTR_MAX, "%.0f", FUNC (ceil) (real_max_error)); + FTOSTR (prmestr, FSTR_MAX, "%.0f", FUNC (ceil) (prev_real_max_error)); + FTOSTR (imestr, FSTR_MAX, "%.0f", FUNC (ceil) (imag_max_error)); + FTOSTR (pimestr, FSTR_MAX, "%.0f", FUNC (ceil) (prev_imag_max_error)); printf ("Maximal error of real part of: %s\n", func_name); printf (" is : %s ulp\n", rmestr); printf (" accepted: %s ulp\n", prmestr); @@ -884,12 +905,10 @@ check_float_internal (const char *test_name, FLOAT computed, FLOAT expected, { 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); + fmt_ftostr (dstrn, FSTR_MAX, 1, TYPE_DECIMAL_DIG - 1, "e", diff); + fmt_ftostr (dstrx, FSTR_MAX, 1, TYPE_HEX_DIG - 1, "a", diff); + fmt_ftostr (ustrn, FSTR_MAX, 1, 4, "f", ulps); + fmt_ftostr (mustrn, FSTR_MAX, 1, 4, "f", max_ulp); printf (" difference: %s %s\n", dstrn, dstrx); printf (" ulp : %s\n", ustrn); printf (" max.ulp : %s\n", mustrn); diff --git a/math/test-double.h b/math/test-double.h index e172b8f..170f03c 100644 --- a/math/test-double.h +++ b/math/test-double.h @@ -18,13 +18,10 @@ #define FUNC(function) function #define FLOAT double -#define PRINTF_EXPR "e" -#define PRINTF_XEXPR "a" -#define PRINTF_NEXPR "f" #define BUILD_COMPLEX(real, imag) (CMPLX ((real), (imag))) #define PREFIX DBL #define LIT(x) (x) #define TYPE_STR "double" #define LITM(x) x -#define FTOSTR snprintf +#define FTOSTR strfromd #define snan_value_MACRO SNAN diff --git a/math/test-float.h b/math/test-float.h index ea096c8..84d0bd1 100644 --- a/math/test-float.h +++ b/math/test-float.h @@ -18,14 +18,11 @@ #define FUNC(function) function ## f #define FLOAT float -#define PRINTF_EXPR "e" -#define PRINTF_XEXPR "a" -#define PRINTF_NEXPR "f" #define BUILD_COMPLEX(real, imag) (CMPLXF ((real), (imag))) #define PREFIX FLT #define TYPE_STR "float" #define LIT(x) (x ## f) /* Use the double variants of macro constants. */ #define LITM(x) x -#define FTOSTR snprintf +#define FTOSTR strfromf #define snan_value_MACRO SNANF diff --git a/math/test-ldouble.h b/math/test-ldouble.h index 62c9eb8..a18938a 100644 --- a/math/test-ldouble.h +++ b/math/test-ldouble.h @@ -18,13 +18,10 @@ #define FUNC(function) function##l #define FLOAT long double -#define PRINTF_EXPR "Le" -#define PRINTF_XEXPR "La" -#define PRINTF_NEXPR "Lf" #define BUILD_COMPLEX(real, imag) (CMPLXL ((real), (imag))) #define PREFIX LDBL #define TYPE_STR "ldouble" #define LIT(x) (x ## L) #define LITM(x) x ## l -#define FTOSTR snprintf +#define FTOSTR strfroml #define snan_value_MACRO SNANL