about summary refs log tree commit diff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2001-02-07 08:28:15 +0000
committerUlrich Drepper <drepper@redhat.com>2001-02-07 08:28:15 +0000
commit55ae3aa64f473f0a410577507d2603dc9e3e7f4c (patch)
tree97d18d49d10f0e2a7ade049686ac306beff246ae
parent18e532f18e013238970458ac35321b556d893912 (diff)
downloadglibc-55ae3aa64f473f0a410577507d2603dc9e3e7f4c.tar.gz
glibc-55ae3aa64f473f0a410577507d2603dc9e3e7f4c.tar.xz
glibc-55ae3aa64f473f0a410577507d2603dc9e3e7f4c.zip
Never stop prematurely reading digits before the decimal point is found. Compute exponent limit for negative exponents correctly. For numbers ending in all zeros eat the zeroes even before the decimal point if the exponent is negative.
-rw-r--r--stdlib/strtod.c30
1 files changed, 19 insertions, 11 deletions
diff --git a/stdlib/strtod.c b/stdlib/strtod.c
index 49ef2898be..72d2fe453f 100644
--- a/stdlib/strtod.c
+++ b/stdlib/strtod.c
@@ -698,10 +698,7 @@ INTERNAL (STRTOF) (nptr, endptr, group LOCALE_PARAM)
      decimal point, exponent character or any non-FP number character.  */
   startp = cp;
   dig_no = 0;
-  while (dig_no < (base == 16 ? HEXNDIG : NDIG) ||
-	 /* If parsing grouping info, keep going past useful digits
-	    so we can check all the grouping separators.  */
-	 grouping)
+  while (1)
     {
       if ((c >= L_('0') && c <= L_('9'))
 	  || (base == 16 && TOLOWER (c) >= L_('a') && TOLOWER (c) <= L_('f')))
@@ -760,11 +757,6 @@ INTERNAL (STRTOF) (nptr, endptr, group LOCALE_PARAM)
 	}
     }
 
-  if (dig_no >= (base == 16 ? HEXNDIG : NDIG))
-    /* Too many digits to be representable.  Assigning this to EXPONENT
-       allows us to read the full number but return HUGE_VAL after parsing.  */
-    exponent = MAX_10_EXP;
-
   /* We have the number digits in the integer part.  Whether these are all or
      any is really a fractional digit will be decided later.  */
   int_no = dig_no;
@@ -820,11 +812,11 @@ INTERNAL (STRTOF) (nptr, endptr, group LOCALE_PARAM)
 	  /* Get the exponent limit. */
 	  if (base == 16)
 	    exp_limit = (exp_negative ?
-			 -MIN_EXP + MANT_DIG - 4 * int_no :
+			 -MIN_EXP + MANT_DIG + 4 * int_no :
 			 MAX_EXP - 4 * int_no + lead_zero);
 	  else
 	    exp_limit = (exp_negative ?
-			 -MIN_10_EXP + MANT_DIG - int_no :
+			 -MIN_10_EXP + MANT_DIG + int_no :
 			 MAX_10_EXP - int_no + lead_zero);
 
 	  do
@@ -882,6 +874,22 @@ INTERNAL (STRTOF) (nptr, endptr, group LOCALE_PARAM)
       assert (dig_no >= int_no);
     }
 
+  if (dig_no == int_no && dig_no > 0 && exponent < 0)
+    do
+      {
+	while (expp[-1] < L_('0') || expp[-1] > L_('9'))
+	  --expp;
+
+	if (expp[-1] != L_('0'))
+	  break;
+
+	--expp;
+	--dig_no;
+	--int_no;
+	++exponent;
+      }
+    while (dig_no > 0 && exponent < 0);
+
  number_parsed:
 
   /* The whole string is parsed.  Store the address of the next character.  */