diff options
Diffstat (limited to 'stdlib/strtod_l.c')
-rw-r--r-- | stdlib/strtod_l.c | 38 |
1 files changed, 20 insertions, 18 deletions
diff --git a/stdlib/strtod_l.c b/stdlib/strtod_l.c index e13f1086da..b4e4819c87 100644 --- a/stdlib/strtod_l.c +++ b/stdlib/strtod_l.c @@ -662,20 +662,20 @@ ____STRTOF_INTERNAL (nptr, endptr, group, loc) /* If no other digit but a '0' is found the result is 0.0. Return current read pointer. */ - if ((c < L_('0') || c > L_('9')) - && (base == 16 && (c < (CHAR_TYPE) TOLOWER (L_('a')) - || c > (CHAR_TYPE) TOLOWER (L_('f')))) + if (!((c >= L_('0') && c <= L_('9')) + || (base == 16 && ((CHAR_TYPE) TOLOWER (c) >= L_('a') + && (CHAR_TYPE) TOLOWER (c) <= L_('f'))) #ifdef USE_WIDE_CHAR - && c != (wint_t) decimal + || c == (wint_t) decimal #else - && ({ for (cnt = 0; decimal[cnt] != '\0'; ++cnt) + || ({ for (cnt = 0; decimal[cnt] != '\0'; ++cnt) if (decimal[cnt] != cp[cnt]) break; - decimal[cnt] != '\0'; }) + decimal[cnt] == '\0'; }) #endif - && (base == 16 && (cp == start_of_digits - || (CHAR_TYPE) TOLOWER (c) != L_('p'))) - && (base != 16 && (CHAR_TYPE) TOLOWER (c) != L_('e'))) + || (base == 16 && (cp != start_of_digits + && (CHAR_TYPE) TOLOWER (c) == L_('p'))) + || (base != 16 && (CHAR_TYPE) TOLOWER (c) == L_('e')))) { #ifdef USE_WIDE_CHAR tp = __correctly_grouped_prefixwc (start_of_digits, cp, thousands, @@ -721,7 +721,7 @@ ____STRTOF_INTERNAL (nptr, endptr, group, loc) c = *++cp; } - if (grouping && dig_no > 0) + if (grouping && cp > start_of_digits) { /* Check the grouping of the digits. */ #ifdef USE_WIDE_CHAR @@ -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')); @@ -888,7 +890,7 @@ ____STRTOF_INTERNAL (nptr, endptr, group, loc) --expp; --dig_no; --int_no; - ++exponent; + exponent += base == 16 ? 4 : 1; } while (dig_no > 0 && exponent < 0); |