mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-30 22:43:12 +03:00
[BZ #4070]
2007-02-21 Ulrich Drepper <drepper@redhat.com> [BZ #4070] * stdio-common/printf_fp.c (___printf_fp): Handle a few more * stdio-common/tfformat.c (sprint_doubles): Some more tests. special cases.
This commit is contained in:
@ -1,3 +1,10 @@
|
|||||||
|
2007-02-21 Ulrich Drepper <drepper@redhat.com>
|
||||||
|
|
||||||
|
[BZ #4070]
|
||||||
|
* stdio-common/printf_fp.c (___printf_fp): Handle a few more
|
||||||
|
* stdio-common/tfformat.c (sprint_doubles): Some more tests.
|
||||||
|
special cases.
|
||||||
|
|
||||||
2007-02-19 Ulrich Drepper <drepper@redhat.com>
|
2007-02-19 Ulrich Drepper <drepper@redhat.com>
|
||||||
|
|
||||||
* stdio-common/printf_fp.c (___printf_fp): Cleanups and minor
|
* stdio-common/printf_fp.c (___printf_fp): Cleanups and minor
|
||||||
|
@ -105,14 +105,14 @@ extern struct pthread_functions __libc_pthread_functions attribute_hidden;
|
|||||||
extern int __libc_pthread_functions_init attribute_hidden;
|
extern int __libc_pthread_functions_init attribute_hidden;
|
||||||
|
|
||||||
#ifdef PTR_DEMANGLE
|
#ifdef PTR_DEMANGLE
|
||||||
# define PTHFCT_CALL(fct, params) \
|
|
||||||
__libc_pthread_functions.fct params
|
|
||||||
#else
|
|
||||||
# define PTHFCT_CALL(fct, params) \
|
# define PTHFCT_CALL(fct, params) \
|
||||||
({ __typeof (__libc_pthread_functions.fct) __p; \
|
({ __typeof (__libc_pthread_functions.fct) __p; \
|
||||||
__p = __libc_pthread_functions.fct; \
|
__p = __libc_pthread_functions.fct; \
|
||||||
PTR_DEMANGLE (__p); \
|
PTR_DEMANGLE (__p); \
|
||||||
__p params; })
|
__p params; })
|
||||||
|
#else
|
||||||
|
# define PTHFCT_CALL(fct, params) \
|
||||||
|
__libc_pthread_functions.fct params
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* pthread-functions.h */
|
#endif /* pthread-functions.h */
|
||||||
|
@ -926,7 +926,8 @@ ___printf_fp (FILE *fp,
|
|||||||
|
|
||||||
/* Generate the needed number of fractional digits. */
|
/* Generate the needed number of fractional digits. */
|
||||||
int fracdig_no = 0;
|
int fracdig_no = 0;
|
||||||
while (fracdig_no < fracdig_min
|
int added_zeros = 0;
|
||||||
|
while (fracdig_no < fracdig_min + added_zeros
|
||||||
|| (fracdig_no < fracdig_max && (fracsize > 1 || frac[0] != 0)))
|
|| (fracdig_no < fracdig_max && (fracsize > 1 || frac[0] != 0)))
|
||||||
{
|
{
|
||||||
++fracdig_no;
|
++fracdig_no;
|
||||||
@ -937,7 +938,7 @@ ___printf_fp (FILE *fp,
|
|||||||
{
|
{
|
||||||
++fracdig_max;
|
++fracdig_max;
|
||||||
if (fracdig_min > 0)
|
if (fracdig_min > 0)
|
||||||
++fracdig_min;
|
++added_zeros;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -974,11 +975,23 @@ ___printf_fp (FILE *fp,
|
|||||||
{
|
{
|
||||||
/* Process fractional digits. Terminate if not rounded or
|
/* Process fractional digits. Terminate if not rounded or
|
||||||
radix character is reached. */
|
radix character is reached. */
|
||||||
|
int removed = 0;
|
||||||
while (*--wtp != decimalwc && *wtp == L'9')
|
while (*--wtp != decimalwc && *wtp == L'9')
|
||||||
*wtp = L'0';
|
{
|
||||||
|
*wtp = L'0';
|
||||||
|
++removed;
|
||||||
|
}
|
||||||
|
if (removed == fracdig_min && added_zeros > 0)
|
||||||
|
--added_zeros;
|
||||||
if (*wtp != decimalwc)
|
if (*wtp != decimalwc)
|
||||||
/* Round up. */
|
/* Round up. */
|
||||||
(*wtp)++;
|
(*wtp)++;
|
||||||
|
else if (__builtin_expect (spec == 'g' && type == 'f' && info->alt,
|
||||||
|
0))
|
||||||
|
/* This is a special case: the rounded number is 1.0,
|
||||||
|
the format is 'g' or 'G', and the alternative format
|
||||||
|
is selected. This means the result mist be "1.". */
|
||||||
|
--added_zeros;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fracdig_no == 0 || *wtp == decimalwc)
|
if (fracdig_no == 0 || *wtp == decimalwc)
|
||||||
@ -1045,7 +1058,7 @@ ___printf_fp (FILE *fp,
|
|||||||
|
|
||||||
do_expo:
|
do_expo:
|
||||||
/* Now remove unnecessary '0' at the end of the string. */
|
/* Now remove unnecessary '0' at the end of the string. */
|
||||||
while (fracdig_no > fracdig_min && *(wcp - 1) == L'0')
|
while (fracdig_no > fracdig_min + added_zeros && *(wcp - 1) == L'0')
|
||||||
{
|
{
|
||||||
--wcp;
|
--wcp;
|
||||||
--fracdig_no;
|
--fracdig_no;
|
||||||
@ -1063,26 +1076,41 @@ ___printf_fp (FILE *fp,
|
|||||||
/* Write the exponent if it is needed. */
|
/* Write the exponent if it is needed. */
|
||||||
if (type != 'f')
|
if (type != 'f')
|
||||||
{
|
{
|
||||||
*wcp++ = (wchar_t) type;
|
if (__builtin_expect (expsign != 0 && exponent == 4 && spec == 'g', 0))
|
||||||
*wcp++ = expsign ? L'-' : L'+';
|
{
|
||||||
|
/* This is another special case. The exponent of the number is
|
||||||
/* Find the magnitude of the exponent. */
|
really smaller than -4, which requires the 'e'/'E' format.
|
||||||
expscale = 10;
|
But after rounding the number has an exponent of -4. */
|
||||||
while (expscale <= exponent)
|
assert (wcp >= wstartp + 2);
|
||||||
expscale *= 10;
|
assert (wstartp[0] == L'1');
|
||||||
|
__wmemcpy (wstartp, L"0.0001", 6);
|
||||||
if (exponent < 10)
|
wstartp[1] = decimalwc;
|
||||||
/* Exponent always has at least two digits. */
|
wmemset (wstartp + 6, L'0', wcp - (wstartp + 2));
|
||||||
*wcp++ = L'0';
|
wcp += 4;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
do
|
{
|
||||||
{
|
*wcp++ = (wchar_t) type;
|
||||||
expscale /= 10;
|
*wcp++ = expsign ? L'-' : L'+';
|
||||||
*wcp++ = L'0' + (exponent / expscale);
|
|
||||||
exponent %= expscale;
|
/* Find the magnitude of the exponent. */
|
||||||
}
|
expscale = 10;
|
||||||
while (expscale > 10);
|
while (expscale <= exponent)
|
||||||
*wcp++ = L'0' + exponent;
|
expscale *= 10;
|
||||||
|
|
||||||
|
if (exponent < 10)
|
||||||
|
/* Exponent always has at least two digits. */
|
||||||
|
*wcp++ = L'0';
|
||||||
|
else
|
||||||
|
do
|
||||||
|
{
|
||||||
|
expscale /= 10;
|
||||||
|
*wcp++ = L'0' + (exponent / expscale);
|
||||||
|
exponent %= expscale;
|
||||||
|
}
|
||||||
|
while (expscale > 10);
|
||||||
|
*wcp++ = L'0' + exponent;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compute number of characters which must be filled with the padding
|
/* Compute number of characters which must be filled with the padding
|
||||||
@ -1123,15 +1151,14 @@ ___printf_fp (FILE *fp,
|
|||||||
else
|
else
|
||||||
thousands_sep_len = strlen (thousands_sep);
|
thousands_sep_len = strlen (thousands_sep);
|
||||||
|
|
||||||
if (buffer_malloced)
|
if (__builtin_expect (buffer_malloced, 0))
|
||||||
{
|
{
|
||||||
buffer = (char *) malloc (2 + chars_needed + decimal_len
|
buffer = (char *) malloc (2 + chars_needed + decimal_len
|
||||||
+ ngroups * thousands_sep_len);
|
+ ngroups * thousands_sep_len);
|
||||||
if (buffer == NULL)
|
if (buffer == NULL)
|
||||||
{
|
{
|
||||||
/* Signal an error to the caller. */
|
/* Signal an error to the caller. */
|
||||||
if (buffer_malloced)
|
free (wbuffer);
|
||||||
free (wbuffer);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1165,7 +1192,7 @@ ___printf_fp (FILE *fp,
|
|||||||
PRINT (tmpptr, wstartp, wide ? wcp - wstartp : cp - tmpptr);
|
PRINT (tmpptr, wstartp, wide ? wcp - wstartp : cp - tmpptr);
|
||||||
|
|
||||||
/* Free the memory if necessary. */
|
/* Free the memory if necessary. */
|
||||||
if (buffer_malloced)
|
if (__builtin_expect (buffer_malloced, 0))
|
||||||
{
|
{
|
||||||
free (buffer);
|
free (buffer);
|
||||||
free (wbuffer);
|
free (wbuffer);
|
||||||
|
@ -4012,6 +4012,14 @@ sprint_double_type sprint_doubles[] =
|
|||||||
{__LINE__, 16, "0x1.0p+4", "%.1a"},
|
{__LINE__, 16, "0x1.0p+4", "%.1a"},
|
||||||
{__LINE__, 16, "0x1.00000000000000000000p+4", "%.20a"},
|
{__LINE__, 16, "0x1.00000000000000000000p+4", "%.20a"},
|
||||||
{__LINE__, 4444.88888888, "4445", "%2.F"},
|
{__LINE__, 4444.88888888, "4445", "%2.F"},
|
||||||
|
{__LINE__, 0.956, "1", "%.0g"},
|
||||||
|
{__LINE__, 1.0956, "1.", "%#.0g"},
|
||||||
|
{__LINE__, 0.956, "1.", "%#.0g"},
|
||||||
|
{__LINE__, 0.0956, "0.1", "%#.0g"},
|
||||||
|
{__LINE__, 0.00956, "0.01", "%#.0g"},
|
||||||
|
{__LINE__, 0.000956, "0.001", "%#.0g"},
|
||||||
|
{__LINE__, 0.000098, "0.0001", "%#.0g"},
|
||||||
|
{__LINE__, 0.0000996, "0.00010", "%#.2g"},
|
||||||
|
|
||||||
{0 }
|
{0 }
|
||||||
|
|
||||||
@ -4023,13 +4031,8 @@ sprint_double_type sprint_doubles[] =
|
|||||||
|
|
||||||
int required_precision = 13;
|
int required_precision = 13;
|
||||||
|
|
||||||
#if defined(__STDC__) || defined(__cplusplus)
|
|
||||||
static int
|
static int
|
||||||
matches (register char *result, register const char *desired)
|
matches (register char *result, register const char *desired)
|
||||||
#else
|
|
||||||
int matches(result, desired)
|
|
||||||
register char *result; register const char *desired;
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
int digits_seen = 0;
|
int digits_seen = 0;
|
||||||
for (;; result++, desired++) {
|
for (;; result++, desired++) {
|
||||||
@ -4080,7 +4083,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
/* And one special test. */
|
/* And one special test. */
|
||||||
{
|
{
|
||||||
const char ref[] = "1.7763568394002504646778106689453125e-15";
|
static const char ref[] = "1.7763568394002504646778106689453125e-15";
|
||||||
int i;
|
int i;
|
||||||
d = 1.0;
|
d = 1.0;
|
||||||
for (i = 1; i < 50; ++i)
|
for (i = 1; i < 50; ++i)
|
||||||
|
Reference in New Issue
Block a user