Index: src/vasprintf.c =================================================================== --- src/vasprintf.c (revision 13642) +++ src/vasprintf.c (revision 13649) @@ -1234,15 +1234,13 @@ Return -1 in case of overflow on the sizes. */ static int regular_eg (struct number_parts *np, mpfr_srcptr p, - const struct printf_spec spec, struct decimal_info *dec_info) + const struct printf_spec spec, struct decimal_info *dec_info, + int keep_trailing_zeros) { char *str; mpfr_exp_t exp; const int uppercase = spec.spec == 'E' || spec.spec == 'G'; - const int spec_g = spec.spec == 'g' || spec.spec == 'G'; - const int keep_trailing_zeros = (spec_g && spec.alt) - || (!spec_g && (spec.prec > 0)); /* sign */ if (MPFR_IS_NEG (p)) @@ -1308,7 +1306,7 @@ np->fp_ptr = str; np->fp_size = str_len; /* Warning! str_len has type size_t, which is unsigned. */ - if ((!spec_g || spec.alt) && spec.prec > 0 && str_len < spec.prec) + if (keep_trailing_zeros && spec.prec > 0 && str_len < spec.prec) { /* add missing trailing zeros */ np->fp_trailing_zeros = spec.prec - str_len; @@ -1369,12 +1367,11 @@ Return -1 in case of overflow on the sizes. */ static int regular_fg (struct number_parts *np, mpfr_srcptr p, - const struct printf_spec spec, struct decimal_info *dec_info) + const struct printf_spec spec, struct decimal_info *dec_info, + int keep_trailing_zeros) { mpfr_exp_t exp; char * str; - const int spec_g = (spec.spec == 'g' || spec.spec == 'G'); - const int keep_trailing_zeros = !spec_g || spec.alt; /* WARNING: an empty precision field is forbidden (it means precision = 6 and it should have been changed to 6 before the function call) */ @@ -1429,7 +1426,7 @@ switch (spec.rnd_mode) { case MPFR_RNDA: - case MPFR_RNDF: /* round_away = 1 needed for spec_g */ + case MPFR_RNDF: /* round_away = 1 needed for %Rg */ round_away = 1; break; case MPFR_RNDZ: @@ -1484,7 +1481,7 @@ else /* only zeros in fractional part */ { - MPFR_ASSERTD (!spec_g); + MPFR_ASSERTD (spec.spec == 'f' || spec.spec == 'F'); np->fp_leading_zeros = spec.prec; } } @@ -1526,7 +1523,7 @@ { MPFR_ASSERTD (str[0] == '1'); np->ip_ptr[0] = '1'; - if (!spec_g || spec.alt) + if (keep_trailing_zeros) np->fp_leading_zeros = spec.prec; } else @@ -1554,7 +1551,7 @@ /* The np->fp_size <= MPFR_INTMAX_MAX test and the cast to mpfr_uintmax_t below allow one to avoid integer overflow. */ - if ((!spec_g || spec.alt) + if (keep_trailing_zeros && spec.prec > 0 && np->fp_size <= MPFR_INTMAX_MAX && ((mpfr_uintmax_t) @@ -1816,12 +1813,12 @@ { if (spec.prec < 0) spec.prec = 6; - if (regular_fg (np, p, spec, NULL) == -1) + if (regular_fg (np, p, spec, NULL, 1) == -1) goto error; } else if (spec.spec == 'e' || spec.spec == 'E') { - if (regular_eg (np, p, spec, NULL) == -1) + if (regular_eg (np, p, spec, NULL, 1) == -1) goto error; } else @@ -1877,7 +1874,7 @@ /* the conversion is with style 'f' */ spec.prec = threshold - x - 1; - if (regular_fg (np, p, spec, &dec_info) == -1) + if (regular_fg (np, p, spec, &dec_info, spec.alt) == -1) goto error; } else @@ -1884,7 +1881,7 @@ { spec.prec = threshold - 1; - if (regular_eg (np, p, spec, &dec_info) == -1) + if (regular_eg (np, p, spec, &dec_info, spec.alt) == -1) goto error; } } Index: tests/tfprintf.c =================================================================== --- tests/tfprintf.c (revision 13642) +++ tests/tfprintf.c (revision 13649) @@ -195,7 +195,7 @@ lo, &ulo); check_length (2, ulo, 36, lu); check_vfprintf (fout, "a. %hi, b. %*f, c. %Re%hn", ush, 3, f, mpfr, &ush); - check_length (3, ush, 29, hu); + check_length (3, ush, 46, hu); check_vfprintf (fout, "a. %hi, b. %f, c. %#.2Rf%n", sh, d, mpfr, &i); check_length (4, i, 29, d); check_vfprintf (fout, "a. %R*A, b. %Fe, c. %i%zn", rnd, mpfr, mpf, sz, @@ -233,12 +233,12 @@ #if (__GNU_MP_VERSION * 10 + __GNU_MP_VERSION_MINOR) >= 42 /* The 'M' specifier was added in gmp 4.2.0 */ check_vfprintf (fout, "a. %Mx b. %Re%Mn", limb[0], mpfr, &limb[0]); - if (limb[0] != 14 + GMP_NUMB_BITS / 4 || + if (limb[0] != 29 + GMP_NUMB_BITS / 4 || limb[1] != MPFR_LIMB_MAX || limb[2] != MPFR_LIMB_MAX) { printf ("Error in test #11: mpfr_vfprintf did not print %d characters" - " as expected\n", 14 + (int) GMP_NUMB_BITS / 4); + " as expected\n", 29 + (int) GMP_NUMB_BITS / 4); exit (1); } @@ -247,12 +247,12 @@ and check it doesn't go through */ check_vfprintf (fout, "a. %Re .b %Nx%Nn", mpfr, limb, limb_size, limb, limb_size - 1); - if (limb[0] != 14 + 3 * GMP_NUMB_BITS / 4 || + if (limb[0] != 29 + 3 * GMP_NUMB_BITS / 4 || limb[1] != MPFR_LIMB_ZERO || limb[2] != MPFR_LIMB_MAX) { printf ("Error in test #12: mpfr_vfprintf did not print %d characters" - " as expected\n", 14 + (int) GMP_NUMB_BITS / 4); + " as expected\n", 29 + (int) GMP_NUMB_BITS / 4); exit (1); } #endif @@ -263,7 +263,7 @@ unsigned long long ullo = 1; check_vfprintf (fout, "a. %Re, b. %llx%Qn", mpfr, ullo, &mpq); - check_length_with_cmp (21, mpq, 16, mpq_cmp_ui (mpq, 16, 1), Qu); + check_length_with_cmp (21, mpq, 31, mpq_cmp_ui (mpq, 31, 1), Qu); check_vfprintf (fout, "a. %lli, b. %Rf%Fn", llo, mpfr, &mpf); check_length_with_cmp (22, mpf, 19, mpf_cmp_ui (mpf, 19), Fg); } Index: tests/tsprintf.c =================================================================== --- tests/tsprintf.c (revision 13642) +++ tests/tsprintf.c (revision 13649) @@ -225,8 +225,8 @@ decimal (void) { mpfr_prec_t p = 128; - mpfr_t x; - mpfr_t z; + mpfr_t x, y, z; + mpfr_init (z); mpfr_init2 (x, p); @@ -300,10 +300,13 @@ /* positive numbers */ mpfr_set_str (x, "18993474.61279296875", 10, MPFR_RNDN); + mpfr_init2 (y, 59); + mpfr_set (y, x, MPFR_RNDN); mpfr_set_ui (z, 0, MPFR_RNDD); /* simplest case right justified */ - check_sprintf (" 1.899347461279296875e+07", "%30Re", x); + check_sprintf ("1.899347461279296875000000000000000000000e+07", "%30Re", x); + check_sprintf (" 1.899347461279296875e+07", "%30Re", y); check_sprintf (" 2e+07", "%30.0Re", x); check_sprintf (" 18993474.612793", "%30Rf", x); check_sprintf (" 18993474.6127930", "%30.7Rf", x); @@ -316,13 +319,15 @@ check_sprintf (" 0", "%30.0Rg", z); check_sprintf (" 0", "%30.4Rg", z); /* sign or space, pad with leading zeros */ - check_sprintf (" 000001.899347461279296875E+07", "% 030RE", x); + check_sprintf (" 1.899347461279296875000000000000000000000E+07", "% 030RE", x); + check_sprintf (" 000001.899347461279296875E+07", "% 030RE", y); check_sprintf (" 0000000000000000001.89935E+07", "% 030RG", x); check_sprintf (" 0000000000000000000000002E+07", "% 030.0RE", x); check_sprintf (" 0000000000000000000000000E+00", "% 030.0RE", z); check_sprintf (" 00000000000000000000000000000", "% 030.0RF", z); /* sign + or -, left justified */ - check_sprintf ("+1.899347461279296875e+07 ", "%+-30Re", x); + check_sprintf ("+1.899347461279296875000000000000000000000e+07", "%+-30Re", x); + check_sprintf ("+1.899347461279296875e+07 ", "%+-30Re", y); check_sprintf ("+2e+07 ", "%+-30.0Re", x); check_sprintf ("+0e+00 ", "%+-30.0Re", z); check_sprintf ("+0 ", "%+-30.0Rf", z); @@ -342,7 +347,8 @@ check_sprintf ("+0000.0E+00", "%0+#11.1RZE", z); check_sprintf ("+00000000.0", "%0+#11.1RZF", z); /* pad with leading zero */ - check_sprintf ("0000001.899347461279296875e+07", "%030RDe", x); + check_sprintf ("1.899347461279296875000000000000000000000e+07", "%030RDe", x); + check_sprintf ("0000001.899347461279296875e+07", "%030RDe", y); check_sprintf ("00000000000000000000000001e+07", "%030.0RDe", x); /* sign or space, decimal point, left justified */ check_sprintf (" 1.8E+07 ", "%- #11.1RDE", x); @@ -363,8 +369,12 @@ /* neighborhood of 1 */ mpfr_set_str (x, "0.99993896484375", 10, MPFR_RNDN); - check_sprintf ("9.9993896484375E-01 ", "%-20RE", x); - check_sprintf ("9.9993896484375E-01 ", "%-20.RE", x); + mpfr_set_prec (y, 43); + mpfr_set (y, x, MPFR_RNDN); + check_sprintf ("9.999389648437500000000000000000000000000E-01", "%-20RE", x); + check_sprintf ("9.999389648437500000000000000000000000000E-01", "%-20.RE", x); + check_sprintf ("9.9993896484375E-01 ", "%-20RE", y); + check_sprintf ("9.9993896484375E-01 ", "%-20.RE", y); check_sprintf ("1E+00 ", "%-20.0RE", x); check_sprintf ("1.0E+00 ", "%-20.1RE", x); check_sprintf ("1.00E+00 ", "%-20.2RE", x); @@ -399,7 +409,7 @@ /* powers of 10 */ mpfr_set_str (x, "1e17", 10, MPFR_RNDN); - check_sprintf ("1e+17", "%Re", x); + check_sprintf ("1.000000000000000000000000000000000000000e+17", "%Re", x); check_sprintf ("1.000e+17", "%.3Re", x); check_sprintf ("100000000000000000", "%.0Rf", x); check_sprintf ("100000000000000000.0", "%.1Rf", x); @@ -407,7 +417,7 @@ check_sprintf ("100000000000000000.0", "%'.1Rf", x); mpfr_ui_div (x, 1, x, MPFR_RNDN); /* x=1e-17 */ - check_sprintf ("1e-17", "%Re", x); + check_sprintf ("1.000000000000000000000000000000000000000e-17", "%Re", x); check_sprintf ("0.000000", "%Rf", x); check_sprintf ("1e-17", "%Rg", x); check_sprintf ("0.0", "%.1RDf", x); @@ -595,7 +605,7 @@ /* regression in MPFR 3.1.0 (bug introduced in r7761, fixed in r7931) */ check_sprintf ("-10", "%.2Rg", x); - mpfr_clears (x, z, (mpfr_ptr) 0); + mpfr_clears (x, y, z, (mpfr_ptr) 0); return 0; } @@ -849,9 +859,9 @@ rnd = MPFR_RNDD; check_vsprintf ("121%", "%i%%", i); - check_vsprintf ("121% -1.2345678875E+07", "%i%% %RNE", i, x); + check_vsprintf ("121% -1.2345678875000000E+07", "%i%% %RNE", i, x); check_vsprintf ("121, -12345679", "%i, %.0Rf", i, x); - check_vsprintf ("10610209857723, -1.2345678875e+07", "%Zi, %R*e", mpz, rnd, + check_vsprintf ("10610209857723, -1.2345678875000000e+07", "%Zi, %R*e", mpz, rnd, x); check_vsprintf ("-12345678.9, 121", "%.1Rf, %i", x, i); check_vsprintf ("-12345678, 1e240/45b352", "%.0R*f, %Qx", MPFR_RNDZ, x, mpq); @@ -880,7 +890,7 @@ #ifdef PRINTF_L /* under MinGW, -D__USE_MINGW_ANSI_STDIO is required to support %Lf see https://gcc.gnu.org/ml/gcc/2013-03/msg00103.html */ - check_vsprintf ("00000010610209857723, -1.2345678875e+07, 0.032258", + check_vsprintf ("00000010610209857723, -1.2345678875000000e+07, 0.032258", "%.*Zi, %R*e, %Lf", 20, mpz, rnd, x, d); #endif @@ -907,7 +917,7 @@ locale_da_DK (void) { mpfr_prec_t p = 128; - mpfr_t x; + mpfr_t x, y; if (setlocale (LC_ALL, "da_DK") == 0 || localeconv()->decimal_point[0] != ',' || @@ -927,15 +937,19 @@ /* positive numbers */ mpfr_set_str (x, "18993474.61279296875", 10, MPFR_RNDN); + mpfr_init2 (y, 59); + mpfr_set (y, x, MPFR_RNDN); /* simplest case right justified with thousands separator */ - check_sprintf (" 1,899347461279296875e+07", "%'30Re", x); + check_sprintf ("1,899347461279296875000000000000000000000e+07", "%'30Re", x); + check_sprintf (" 1,899347461279296875e+07", "%'30Re", y); check_sprintf (" 1,89935e+07", "%'30Rg", x); check_sprintf (" 18.993.474,61279296875", "%'30.19Rg", x); check_sprintf (" 18.993.474,612793", "%'30Rf", x); /* sign or space, pad, thousands separator with leading zeros */ - check_sprintf (" 000001,899347461279296875E+07", "%' 030RE", x); + check_sprintf (" 1,899347461279296875000000000000000000000E+07", "%' 030RE", x); + check_sprintf (" 000001,899347461279296875E+07", "%' 030RE", y); check_sprintf (" 0000000000000000001,89935E+07", "%' 030RG", x); check_sprintf (" 000000018.993.474,61279296875", "%' 030.19RG", x); check_sprintf (" 00000000000018.993.474,612793", "%' 030RF", x); @@ -960,6 +974,7 @@ check_sprintf ("100" S2 "0000", "%'.4Rf", x); mpfr_clear (x); + mpfr_clear (y); setlocale (LC_ALL, "C"); } Index: tests/tprintf.c =================================================================== --- tests/tprintf.c (revision 13642) +++ tests/tprintf.c (revision 13649) @@ -316,7 +316,7 @@ check_vprintf ("a. %c, b. %Rb, c. %u, d. %li%ln", i, mpfr, i, lo, &ulo); check_length (2, ulo, 36, lu); check_vprintf ("a. %hi, b. %*f, c. %Re%hn", ush, 3, f, mpfr, &ush); - check_length (3, ush, 29, hu); + check_length (3, ush, 46, hu); check_vprintf ("a. %hi, b. %f, c. %#.2Rf%n", sh, d, mpfr, &i); check_length (4, i, 29, d); check_vprintf ("a. %R*A, b. %Fe, c. %i%zn", rnd, mpfr, mpf, sz, &sz); @@ -356,7 +356,7 @@ unsigned long long ullo = 1; check_vprintf ("a. %Re, b. %llx%Qn", mpfr, ullo, &mpq); - check_length_with_cmp (11, mpq, 16, mpq_cmp_ui (mpq, 16, 1), Qu); + check_length_with_cmp (11, mpq, 31, mpq_cmp_ui (mpq, 31, 1), Qu); check_vprintf ("a. %lli, b. %Rf%lln", llo, mpfr, &ullo); check_length (12, ullo, 19, llu); } Index: doc/mpfr.texi =================================================================== --- doc/mpfr.texi (revision 13642) +++ doc/mpfr.texi (revision 13649) @@ -2750,9 +2750,9 @@ @code{NAN}, @code{-INF}, and @code{INF} for @samp{A}, @samp{E}, @samp{F}, and @samp{G} specifiers. -If the @samp{precision} field is not empty, the @code{mpfr_t} number is -rounded to the given precision in the direction specified by the rounding -mode. +The @code{mpfr_t} number is rounded to the given precision in the direction +specified by the rounding mode (see below if the @samp{precision} field is +empty). If the precision is zero with rounding to nearest mode and one of the following @samp{conv} specifiers: @samp{a}, @samp{A}, @samp{b}, @samp{e}, @samp{E}, tie case is rounded to even when it lies between two consecutive @@ -2766,15 +2766,23 @@ If the precision is set to a value greater than the maximum value for an @code{int}, it will be silently reduced down to @code{INT_MAX}. -If the @samp{precision} field is empty (as in @code{%Re} or @code{%.RE}) with -@samp{conv} specifier @samp{e} and @samp{E}, the number is displayed with -enough digits so that it can be read back exactly, assuming that the input and -output variables have the same precision and that the input and output -rounding modes are both rounding to nearest (as for @code{mpfr_get_str}). -The default precision for an empty @samp{precision} field with @samp{conv} +If the @samp{precision} field is empty with @samp{conv} specifier @samp{e} +and @samp{E} (as in @code{%Re} or @code{%.RE}), the chosen precision +(i.e., the number of digits to be displayed after the initial digit and +the decimal point) is +@ifnottex +ceil(@var{p}*log(2)/log(@var{10})), +@end ifnottex +@tex +$\left\lceil @var{p} {\log 2 \over \log @var{10}} \right\rceil$, +@end tex +where @var{p} is the precision of the input variable, matching the choice +done for @code{mpfr_get_str}; thus, if rounding to nearest is used, +outputting the value with an empty @samp{precision} field and reading it +back will yield the original value. +The chosen precision for an empty @samp{precision} field with @samp{conv} specifiers @samp{f}, @samp{F}, @samp{g}, and @samp{G} is 6. - @subsection Functions For all the following functions, if the number of characters that ought to be