1 /* Copyright (C) 1991-1992, 1997, 1999, 2003, 2006, 2008-2010 Free Software
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
30 #ifndef HAVE_LDEXP_IN_LIBC
31 #define HAVE_LDEXP_IN_LIBC 0
33 #ifndef HAVE_RAW_DECL_STRTOD
34 #define HAVE_RAW_DECL_STRTOD 0
37 /* Return true if C is a space in the current locale, avoiding
38 problems with signed char and isspace. */
40 locale_isspace (char c)
43 return isspace (uc) != 0;
46 #if !HAVE_LDEXP_IN_LIBC
47 #define ldexp dummy_ldexp
48 static double ldexp (double x, int exponent) { return x + exponent; }
51 /* Return X * BASE**EXPONENT. Return an extreme value and set errno
52 to ERANGE if underflow or overflow occurs. */
54 scale_radix_exp (double x, int radix, long int exponent)
56 /* If RADIX == 10, this code is neither precise nor fast; it is
57 merely a straightforward and relatively portable approximation.
58 If N == 2, this code is precise on a radix-2 implementation,
59 albeit perhaps not fast if ldexp is not in libc. */
61 long int e = exponent;
63 if (HAVE_LDEXP_IN_LIBC && radix == 2)
64 return ldexp (x, e < INT_MIN ? INT_MIN : INT_MAX < e ? INT_MAX : e);
87 if (r < -DBL_MAX / radix)
92 else if (DBL_MAX / radix < r)
107 /* Parse a number at NPTR; this is a bit like strtol (NPTR, ENDPTR)
108 except there are no leading spaces or signs or "0x", and ENDPTR is
109 nonnull. The number uses a base BASE (either 10 or 16) fraction, a
110 radix RADIX (either 10 or 2) exponent, and exponent character
111 EXPCHAR. To convert from a number of digits to a radix exponent,
112 multiply by RADIX_MULTIPLIER (either 1 or 4). */
114 parse_number (const char *nptr,
115 int base, int radix, int radix_multiplier, char expchar,
118 const char *s = nptr;
119 bool got_dot = false;
120 long int exponent = 0;
128 else if (base == 16 && c_isxdigit (*s))
129 digit = c_tolower (*s) - ('a' - 10);
130 else if (! got_dot && *s == '.')
132 /* Record that we have found the decimal point. */
137 /* Any other character terminates the number. */
140 /* Make sure that multiplication by base will not overflow. */
141 if (num <= DBL_MAX / base)
142 num = num * base + digit;
145 /* The value of the digit doesn't matter, since we have already
146 gotten as many digits as can be represented in a `double'.
147 This doesn't necessarily mean the result will overflow.
148 The exponent may reduce it to within range.
150 We just need to record that there was another
151 digit so that we can multiply by 10 later. */
152 exponent += radix_multiplier;
155 /* Keep track of the number of digits after the decimal point.
156 If we just divided by base here, we might lose precision. */
158 exponent -= radix_multiplier;
161 if (c_tolower (*s) == expchar && ! locale_isspace (s[1]))
163 /* Add any given exponent to the implicit one. */
166 long int value = strtol (s + 1, &end, 10);
171 /* Skip past the exponent, and add in the implicit exponent,
172 resulting in an extreme value on overflow. */
176 ? (value < LONG_MIN - exponent ? LONG_MIN : exponent + value)
177 : (LONG_MAX - exponent < value ? LONG_MAX : exponent + value));
181 *endptr = (char *) s;
182 return scale_radix_exp (num, radix, exponent);
185 static double underlying_strtod (const char *, char **);
187 /* Convert NPTR to a double. If ENDPTR is not NULL, a pointer to the
188 character after the last one used in the number is put in *ENDPTR. */
190 strtod (const char *nptr, char **endptr)
192 bool negative = false;
194 /* The number so far. */
197 const char *s = nptr;
200 /* Eat whitespace. */
201 while (locale_isspace (*s))
205 negative = *s == '-';
206 if (*s == '-' || *s == '+')
209 num = underlying_strtod (s, &end);
211 if (c_isdigit (s[*s == '.']))
213 /* If a hex float was converted incorrectly, do it ourselves. */
214 if (*s == '0' && c_tolower (s[1]) == 'x' && end <= s + 2
215 && c_isxdigit (s[2 + (s[2] == '.')]))
216 num = parse_number (s + 2, 16, 2, 4, 'p', &end);
221 /* Check for infinities and NaNs. */
222 else if (c_tolower (*s) == 'i'
223 && c_tolower (s[1]) == 'n'
224 && c_tolower (s[2]) == 'f')
227 if (c_tolower (*s) == 'i'
228 && c_tolower (s[1]) == 'n'
229 && c_tolower (s[2]) == 'i'
230 && c_tolower (s[3]) == 't'
231 && c_tolower (s[4]) == 'y')
235 else if (c_tolower (*s) == 'n'
236 && c_tolower (s[1]) == 'a'
237 && c_tolower (s[2]) == 'n')
242 const char *p = s + 1;
243 while (c_isalnum (*p))
249 /* If the underlying implementation misparsed the NaN, assume
250 its result is incorrect, and return a NaN. Normally it's
251 better to use the underlying implementation's result, since a
252 nice implementation populates the bits of the NaN according
253 to interpreting n-char-sequence as a hexadecimal number. */
259 /* No conversion could be performed. */
265 *endptr = (char *) s;
266 return negative ? -num : num;
269 /* The "underlying" strtod implementation. This must be defined
270 after strtod because it #undefs strtod. */
272 underlying_strtod (const char *nptr, char **endptr)
274 if (HAVE_RAW_DECL_STRTOD)
276 /* Prefer the native strtod if available. Usually it should
277 work and it should give more-accurate results than our
280 return strtod (nptr, endptr);
284 /* Approximate strtod well enough for this module. There's no
285 need to handle anything but finite unsigned decimal
286 numbers with nonnull ENDPTR. */
287 return parse_number (nptr, 10, 10, 1, 'e', endptr);