[BZ #3673]
authorUlrich Drepper <drepper@redhat.com>
Sun, 10 Dec 2006 01:11:45 +0000 (01:11 +0000)
committerUlrich Drepper <drepper@redhat.com>
Sun, 10 Dec 2006 01:11:45 +0000 (01:11 +0000)
* stdlib/strtod_l.c (____STRTOF_INTERNAL): Fix exp_limit
computation.
* stdlib/Makefile (tests): Add tst-atof2.
* stdlib/tst-atof2.c: New file.

* stdlib/Makefile (tests): Add tst-atof1.
* stdlib/tst-atof1.c: New file.

ChangeLog
stdlib/Makefile
stdlib/strtod_l.c
stdlib/tst-atof2.c [new file with mode: 0644]

index 3400be7..2c37e52 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,8 +1,16 @@
 2006-12-09  Ulrich Drepper  <drepper@redhat.com>
 
+       [BZ #3673]
+       * stdlib/strtod_l.c (____STRTOF_INTERNAL): Fix exp_limit
+       computation.
+       * stdlib/Makefile (tests): Add tst-atof2.
+       * stdlib/tst-atof2.c: New file.
+
        [BZ #3674]
        * stdlib/strtod_l.c (____STRTOF_INTERNAL): Adjust exponent value
        correctly if removing trailing zero of hex-float.
+       * stdlib/Makefile (tests): Add tst-atof1.
+       * stdlib/tst-atof1.c: New file.
 
 2006-12-09  Jakub Jelinek  <jakub@redhat.com>
 
index a0ff427..5387475 100644 (file)
@@ -66,7 +66,8 @@ tests         := tst-strtol tst-strtod testmb testrand testsort testdiv   \
                   test-canon test-canon2 tst-strtoll tst-environ           \
                   tst-xpg-basename tst-random tst-random2 tst-bsearch      \
                   tst-limits tst-rand48 bug-strtod tst-setcontext          \
-                  test-a64l tst-qsort tst-system testmb2 bug-strtod2
+                  test-a64l tst-qsort tst-system testmb2 bug-strtod2       \
+                  tst-atof1 tst-atof2
 
 include ../Makeconfig
 
index b9c2769..6f7e62f 100644 (file)
@@ -759,13 +759,15 @@ ____STRTOF_INTERNAL (nptr, endptr, group, loc)
        }
     }
 
-  /* We have the number digits in the integer part.  Whether these are all or
-     any is really a fractional digit will be decided later.  */
+  /* We have the number of digits in the integer part.  Whether these
+     are all or any is really a fractional digit will be decided
+     later.  */
   int_no = dig_no;
   lead_zero = int_no == 0 ? -1 : 0;
 
-  /* Read the fractional digits.  A special case are the 'american style'
-     numbers like `16.' i.e. with decimal but without trailing digits.  */
+  /* Read the fractional digits.  A special case are the 'american
+     style' numbers like `16.' i.e. with decimal point but without
+     trailing digits.  */
   if (
 #ifdef USE_WIDE_CHAR
       c == (wint_t) decimal
@@ -815,15 +817,16 @@ ____STRTOF_INTERNAL (nptr, endptr, group, loc)
          if (base == 16)
            exp_limit = (exp_negative ?
                         -MIN_EXP + MANT_DIG + 4 * int_no :
-                        MAX_EXP - 4 * int_no + lead_zero);
+                        MAX_EXP - 4 * int_no + 4 * lead_zero + 3);
          else
            exp_limit = (exp_negative ?
                         -MIN_10_EXP + MANT_DIG + int_no :
-                        MAX_10_EXP - int_no + lead_zero);
+                        MAX_10_EXP - int_no + lead_zero + 1);
 
          do
            {
              exponent *= 10;
+             exponent += c - L_('0');
 
              if (exponent > exp_limit)
                /* The exponent is too large/small to represent a valid
@@ -853,7 +856,6 @@ ____STRTOF_INTERNAL (nptr, endptr, group, loc)
                  /* NOTREACHED */
                }
 
-             exponent += c - L_('0');
              c = *++cp;
            }
          while (c >= L_('0') && c <= L_('9'));
diff --git a/stdlib/tst-atof2.c b/stdlib/tst-atof2.c
new file mode 100644 (file)
index 0000000..74dac87
--- /dev/null
@@ -0,0 +1,55 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+static const struct
+{
+  const char *str;
+  const char *expected;
+} tests[] =
+  {
+    { "1e308", "1e+308" },
+    { "100000000e300", "1e+308" },
+    { "0x1p1023", "8.98847e+307" },
+    { "0x1000p1011", "8.98847e+307" },
+    { "0x1p1020", "1.12356e+307" },
+    { "0x0.00001p1040", "1.12356e+307" },
+    { "1e-307", "1e-307" },
+    { "0.000001e-301", "1e-307" },
+    { "0.0000001e-300", "1e-307" },
+    { "0.00000001e-299", "1e-307" },
+    { "1000000e-313", "1e-307" },
+    { "10000000e-314", "1e-307" },
+    { "100000000e-315", "1e-307" },
+    { "0x1p-1021", "4.45015e-308" },
+    { "0x1000p-1033", "4.45015e-308" },
+    { "0x10000p-1037", "4.45015e-308" },
+    { "0x0.001p-1009", "4.45015e-308" },
+    { "0x0.0001p-1005", "4.45015e-308" },
+  };
+#define NTESTS (sizeof (tests) / sizeof (tests[0]))
+
+
+static int
+do_test (void)
+{
+  int status = 0;
+
+  for (int i = 0; i < NTESTS; ++i)
+    {
+      char buf[100];
+      snprintf (buf, sizeof (buf), "%g", atof (tests[i].str));
+      if (strcmp (buf, tests[i].expected) != 0)
+       {
+         printf ("%d: got \"%s\", expected \"%s\"\n",
+                 i, buf, tests[i].expected);
+         status = 1;
+       }
+    }
+
+  return status;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"