Re: [PATCH 6/7] stdio-common: Keep trailing zeros where %#g rounds into a new decade
Adhemerval Zanella Netto <[email protected]>
| Newsgroups | gmane.comp.lib.glibc.alpha |
|---|---|
| Organization | Linaro |
| Message-ID | <[email protected]> |
On 24/08/26 19:16, Matt Turner wrote:
> The g and G conversions choose between the f and e styles according to
> the exponent the value has once rounded to the requested number of
> significant digits. Where the value is small enough for the f style but
> rounding then carries into a new decade, printf_fp rewrites the digits
> it has already produced into the e style, recomputing along the way how
> many fractional digits the leading digit now leaves room for.
>
> FRACDIG_MIN, which the alternative form sets to the number of fractional
> digits that have to be retained rather than stripped, was left behind at
> the value computed for the f style. Where the value filled the whole
> integer part that is zero, so all the fractional digits were then
> stripped from a result the '#' flag requires to keep them:
>
> printf ("%#.2g", 99.9) gave "1.e+02" rather than "1.0e+02"
> printf ("%#g", 999999.9) gave "1.e+06" rather than "1.00000e+06"
>
> Update FRACDIG_MIN along with FRACDIG_MAX. Without the alternative form
> nothing retains trailing zeros, so the outcome is unchanged there.
>
> None of the values the conversion tests iterate over round this way, so
> add one that does at a precision they cover.
>
> Tested on x86_64-linux-gnu.
LGTM, thanks. I think this can be installed independently of the set and
I think we should open a bug report to track it.
Reviewed-by: Adhemerval Zanella <[email protected]>
> ---
> stdio-common/printf_fp.c | 5 +++++
> stdio-common/tst-printf-format-skeleton-double.c | 2 +-
> stdio-common/tst-printf-format-skeleton-ldouble.c | 2 +-
> 3 files changed, 7 insertions(+), 2 deletions(-)
>
> diff --git ./stdio-common/printf_fp.c ./stdio-common/printf_fp.c
> index b8f8c5fc07..97bd6afda3 100644
> --- ./stdio-common/printf_fp.c
> +++ ./stdio-common/printf_fp.c
> @@ -896,6 +896,11 @@ __printf_fp_buffer_1 (struct __printf_buffer *buf, locale_t loc,
> fracdig_no += intdig_no;
> intdig_no = 1;
> fracdig_max = intdig_max - intdig_no;
> + if (info->alt)
> + /* The alternative form retains trailing zeros, and
> + the number of fractional digits it has to retain
> + has just changed along with FRACDIG_MAX. */
> + fracdig_min = fracdig_max;
> ++p.exponent;
> /* Now we must print the p.exponent. */
> p.type = isupper (info->spec) ? 'E' : 'e';
> diff --git ./stdio-common/tst-printf-format-skeleton-double.c ./stdio-common/tst-printf-format-skeleton-double.c
> index ae3acb00f7..333bd568a2 100644
> --- ./stdio-common/tst-printf-format-skeleton-double.c
> +++ ./stdio-common/tst-printf-format-skeleton-double.c
> @@ -30,7 +30,7 @@
> typedef double type_t;
> static const type_t vals[] =
> { -HUGE_VAL, -DBL_MAX, -DBL_MIN, -0.0, -NAN, NAN, 0, DBL_TRUE_MIN,
> - DBL_MIN, DBL_MAX, HUGE_VAL };
> + DBL_MIN, 99.9, DBL_MAX, HUGE_VAL };
> static const char length[] = "";
>
> #include "tst-printf-format-skeleton.c"
> diff --git ./stdio-common/tst-printf-format-skeleton-ldouble.c ./stdio-common/tst-printf-format-skeleton-ldouble.c
> index e323d621bb..0c828ec3b5 100644
> --- ./stdio-common/tst-printf-format-skeleton-ldouble.c
> +++ ./stdio-common/tst-printf-format-skeleton-ldouble.c
> @@ -31,7 +31,7 @@
> typedef long double type_t;
> static const type_t vals[] =
> { -HUGE_VAL, -LDBL_MAX, -LDBL_MIN, -0.0, -NAN, NAN, 0, LDBL_TRUE_MIN,
> - LDBL_MIN, LDBL_MAX, HUGE_VAL };
> + LDBL_MIN, 99.9L, LDBL_MAX, HUGE_VAL };
> static const char length[] = "L";
>
> #ifndef TIMEOUT