This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [PATCH] remove nested function hack_digit
- From: Konstantin Serebryany <konstantin dot s dot serebryany at gmail dot com>
- To: Andreas Schwab <schwab at linux-m68k dot org>
- Cc: Roland McGrath <roland at hack dot frob dot com>, GNU C Library <libc-alpha at sourceware dot org>
- Date: Mon, 15 Sep 2014 18:53:30 -0700
- Subject: Re: [PATCH] remove nested function hack_digit
- Authentication-results: sourceware.org; auth=none
- References: <CAGQ9bdxUJaUzz=ndu-qnhkPGAH7=m5mFKxpDag=H693TeA2ORw at mail dot gmail dot com> <87a960l9ze dot fsf at igel dot home>
Yep. I've realized that I've interpreted the test results incorrectly
(missed the failing tests).
The following patch passes tests.
On Mon, Sep 15, 2014 at 4:50 PM, Andreas Schwab <schwab@linux-m68k.org> wrote:
> Konstantin Serebryany <konstantin.s.serebryany@gmail.com> writes:
>
>> + if (expsign != 0 && type == 'f' && exponent-- > 0)
>
>> + fracsize = scalesize;
>
>> + --fracsize;
>
>> + fracsize = 1;
>
>> + frac[fracsize++] = _cy;
>
> All these side effects won't work any more.
>
> Andreas.
>
> --
> Andreas Schwab, schwab@linux-m68k.org
> GPG Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5
> "And now for something completely different."
diff --git a/stdio-common/printf_fp.c b/stdio-common/printf_fp.c
index 9cd4b4b..679cb70 100644
--- a/stdio-common/printf_fp.c
+++ b/stdio-common/printf_fp.c
@@ -148,6 +148,49 @@ static wchar_t *group_number (wchar_t *buf, wchar_t *bufend,
wchar_t thousands_sep, int ngroups)
internal_function;
+static wchar_t hack_digit (int expsign, int type, int *exponent,
+ mp_limb_t *frac, mp_size_t *fracsize,
+ mp_limb_t *scale, mp_size_t scalesize,
+ mp_limb_t *tmp)
+{
+ mp_limb_t hi;
+
+ if (expsign != 0 && type == 'f' && (*exponent)-- > 0)
+ hi = 0;
+ else if (scalesize == 0)
+ {
+ hi = frac[*fracsize - 1];
+ frac[*fracsize - 1] = __mpn_mul_1 (frac, frac, *fracsize - 1, 10);
+ }
+ else
+ {
+ if (*fracsize < scalesize)
+ hi = 0;
+ else
+ {
+ hi = mpn_divmod (tmp, frac, *fracsize, scale, scalesize);
+ tmp[*fracsize - scalesize] = hi;
+ hi = tmp[0];
+
+ *fracsize = scalesize;
+ while (*fracsize != 0 && frac[*fracsize - 1] == 0)
+ --(*fracsize);
+ if (*fracsize == 0)
+ {
+ /* We're not prepared for an mpn variable with zero
+ limbs. */
+ *fracsize = 1;
+ return L'0' + hi;
+ }
+ }
+
+ mp_limb_t _cy = __mpn_mul_1 (frac, frac, *fracsize, 10);
+ if (_cy != 0)
+ frac[(*fracsize)++] = _cy;
+ }
+
+ return L'0' + hi;
+}
int
___printf_fp (FILE *fp,
@@ -213,50 +256,6 @@ ___printf_fp (FILE *fp,
/* Flag whether wbuffer is malloc'ed or not. */
int buffer_malloced = 0;
- auto wchar_t hack_digit (void);
-
- wchar_t hack_digit (void)
- {
- mp_limb_t hi;
-
- if (expsign != 0 && type == 'f' && exponent-- > 0)
- hi = 0;
- else if (scalesize == 0)
- {
- hi = frac[fracsize - 1];
- frac[fracsize - 1] = __mpn_mul_1 (frac, frac, fracsize - 1, 10);
- }
- else
- {
- if (fracsize < scalesize)
- hi = 0;
- else
- {
- hi = mpn_divmod (tmp, frac, fracsize, scale, scalesize);
- tmp[fracsize - scalesize] = hi;
- hi = tmp[0];
-
- fracsize = scalesize;
- while (fracsize != 0 && frac[fracsize - 1] == 0)
- --fracsize;
- if (fracsize == 0)
- {
- /* We're not prepared for an mpn variable with zero
- limbs. */
- fracsize = 1;
- return L'0' + hi;
- }
- }
-
- mp_limb_t _cy = __mpn_mul_1 (frac, frac, fracsize, 10);
- if (_cy != 0)
- frac[fracsize++] = _cy;
- }
-
- return L'0' + hi;
- }
-
-
/* Figure out the decimal point character. */
if (info->extra == 0)
{
@@ -914,7 +913,8 @@ ___printf_fp (FILE *fp,
while (intdig_no < intdig_max)
{
++intdig_no;
- *wcp++ = hack_digit ();
+ *wcp++ = hack_digit (expsign, type, &exponent, frac, &fracsize,
+ scale, scalesize, tmp);
}
significant = 1;
if (info->alt
@@ -938,7 +938,8 @@ ___printf_fp (FILE *fp,
|| (fracdig_no < fracdig_max && (fracsize > 1 || frac[0] != 0)))
{
++fracdig_no;
- *wcp = hack_digit ();
+ *wcp = hack_digit (expsign, type, &exponent, frac, &fracsize,
+ scale, scalesize, tmp);
if (*wcp++ != L'0')
significant = 1;
else if (significant == 0)
@@ -951,7 +952,8 @@ ___printf_fp (FILE *fp,
/* Do rounding. */
wchar_t last_digit = wcp[-1] != decimalwc ? wcp[-1] : wcp[-2];
- wchar_t next_digit = hack_digit ();
+ wchar_t next_digit = hack_digit (expsign, type, &exponent, frac, &fracsize,
+ scale, scalesize, tmp);
bool more_bits;
if (next_digit != L'0' && next_digit != L'5')
more_bits = true;