1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-07-30 22:43:12 +03:00
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:
Ulrich Drepper
2007-02-21 08:57:44 +00:00
parent 4c02bf1adf
commit 0f7769f736
4 changed files with 73 additions and 36 deletions

View File

@ -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

View File

@ -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 */

View File

@ -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);

View File

@ -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)