]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
[BZ #4070]
authorUlrich Drepper <drepper@redhat.com>
Wed, 21 Feb 2007 08:57:44 +0000 (08:57 +0000)
committerUlrich Drepper <drepper@redhat.com>
Wed, 21 Feb 2007 08:57:44 +0000 (08:57 +0000)
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.

ChangeLog
nptl/sysdeps/pthread/pthread-functions.h
stdio-common/printf_fp.c
stdio-common/tfformat.c

index e7dfff6a112e72861cfc84f6fd2bd1d8b37d3323..30d4c8291a0a1813061ccc89e2395c4a7f7be52e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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>
 
        * stdio-common/printf_fp.c (___printf_fp): Cleanups and minor
index ff1e6e9c49d77b0e196b5bc98a9623b9d244aa5b..a13b9370322457e8cbf107bed9807441f43b8a46 100644 (file)
@@ -105,14 +105,14 @@ extern struct pthread_functions __libc_pthread_functions attribute_hidden;
 extern int __libc_pthread_functions_init attribute_hidden;
 
 #ifdef PTR_DEMANGLE
-# define PTHFCT_CALL(fct, params) \
-  __libc_pthread_functions.fct params
-#else
 # define PTHFCT_CALL(fct, params) \
   ({ __typeof (__libc_pthread_functions.fct) __p;                            \
      __p = __libc_pthread_functions.fct;                                     \
      PTR_DEMANGLE (__p);                                                     \
      __p params; })
+#else
+# define PTHFCT_CALL(fct, params) \
+  __libc_pthread_functions.fct params
 #endif
 
 #endif /* pthread-functions.h */
index cbc31438f292273a55064cf241a241756a2e7a00..c27c0d496cf3d40e67c1b3eb860f9a561cadffe8 100644 (file)
@@ -926,7 +926,8 @@ ___printf_fp (FILE *fp,
 
     /* Generate the needed number of fractional digits.         */
     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;
@@ -937,7 +938,7 @@ ___printf_fp (FILE *fp,
          {
            ++fracdig_max;
            if (fracdig_min > 0)
-             ++fracdig_min;
+             ++added_zeros;
          }
       }
 
@@ -974,11 +975,23 @@ ___printf_fp (FILE *fp,
          {
            /* Process fractional digits.  Terminate if not rounded or
               radix character is reached.  */
+           int removed = 0;
            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)
              /* Round up.  */
              (*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)
@@ -1045,7 +1058,7 @@ ___printf_fp (FILE *fp,
 
   do_expo:
     /* 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;
        --fracdig_no;
@@ -1063,26 +1076,41 @@ ___printf_fp (FILE *fp,
     /* Write the exponent if it is needed.  */
     if (type != 'f')
       {
-       *wcp++ = (wchar_t) type;
-       *wcp++ = expsign ? L'-' : L'+';
+       if (__builtin_expect (expsign != 0 && exponent == 4 && spec == 'g', 0))
+         {
+           /* This is another special case.  The exponent of the number is
+              really smaller than -4, which requires the 'e'/'E' format.
+              But after rounding the number has an exponent of -4.  */
+           assert (wcp >= wstartp + 2);
+           assert (wstartp[0] == L'1');
+           __wmemcpy (wstartp, L"0.0001", 6);
+           wstartp[1] = decimalwc;
+           wmemset (wstartp + 6, L'0', wcp - (wstartp + 2));
+           wcp += 4;
+         }
+       else
+         {
+           *wcp++ = (wchar_t) type;
+           *wcp++ = expsign ? L'-' : L'+';
 
-       /* Find the magnitude of the exponent.  */
-       expscale = 10;
-       while (expscale <= exponent)
-         expscale *= 10;
+           /* Find the magnitude of the exponent.      */
+           expscale = 10;
+           while (expscale <= 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;
+           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
@@ -1123,15 +1151,14 @@ ___printf_fp (FILE *fp,
          else
            thousands_sep_len = strlen (thousands_sep);
 
-         if (buffer_malloced)
+         if (__builtin_expect (buffer_malloced, 0))
            {
              buffer = (char *) malloc (2 + chars_needed + decimal_len
                                        + ngroups * thousands_sep_len);
              if (buffer == NULL)
                {
                  /* Signal an error to the caller.  */
-                 if (buffer_malloced)
-                   free (wbuffer);
+                 free (wbuffer);
                  return -1;
                }
            }
@@ -1165,7 +1192,7 @@ ___printf_fp (FILE *fp,
       PRINT (tmpptr, wstartp, wide ? wcp - wstartp : cp - tmpptr);
 
       /* Free the memory if necessary.  */
-      if (buffer_malloced)
+      if (__builtin_expect (buffer_malloced, 0))
        {
          free (buffer);
          free (wbuffer);
index ea7365b2c99ed38858fe74356fc5d875460cc387..0370834e9f1c0dc8ed6d95ecc60f461d83bfe834 100644 (file)
@@ -4012,6 +4012,14 @@ sprint_double_type sprint_doubles[] =
   {__LINE__, 16,                       "0x1.0p+4", "%.1a"},
   {__LINE__, 16,                       "0x1.00000000000000000000p+4", "%.20a"},
   {__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 }
 
@@ -4023,13 +4031,8 @@ sprint_double_type sprint_doubles[] =
 
 int required_precision = 13;
 
-#if defined(__STDC__) || defined(__cplusplus)
 static int
 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;
     for (;; result++, desired++) {
@@ -4080,7 +4083,7 @@ int main(int argc, char *argv[])
 
   /* And one special test.  */
   {
-    const char ref[] = "1.7763568394002504646778106689453125e-15";
+    static const char ref[] = "1.7763568394002504646778106689453125e-15";
     int i;
     d = 1.0;
     for (i = 1; i < 50; ++i)