61887598cab0543097841b015906ffe526747013
[gnulib.git] / lib / strtod.c
1 /* Copyright (C) 1991-1992, 1997, 1999, 2003, 2006, 2008-2010 Free Software
2    Foundation, Inc.
3
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.
8
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.
13
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/>.  */
16
17 #include <config.h>
18
19 #include <stdlib.h>
20
21 #include <ctype.h>
22 #include <errno.h>
23 #include <float.h>
24 #include <limits.h>
25 #include <math.h>
26 #include <stdbool.h>
27
28 #include "c-ctype.h"
29
30 #ifndef HAVE_LDEXP_IN_LIBC
31 #define HAVE_LDEXP_IN_LIBC 0
32 #endif
33 #ifndef HAVE_RAW_DECL_STRTOD
34 #define HAVE_RAW_DECL_STRTOD 0
35 #endif
36
37 /* Return true if C is a space in the current locale, avoiding
38    problems with signed char and isspace.  */
39 static bool
40 locale_isspace (char c)
41 {
42   unsigned char uc = c;
43   return isspace (uc) != 0;
44 }
45
46 #if !HAVE_LDEXP_IN_LIBC
47  #define ldexp dummy_ldexp
48  static double ldexp (double x, int exponent) { return x + exponent; }
49 #endif
50
51 /* Return X * BASE**EXPONENT.  Return an extreme value and set errno
52    to ERANGE if underflow or overflow occurs.  */
53 static double
54 scale_radix_exp (double x, int radix, long int exponent)
55 {
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.  */
60
61   long int e = exponent;
62
63   if (HAVE_LDEXP_IN_LIBC && radix == 2)
64     return ldexp (x, e < INT_MIN ? INT_MIN : INT_MAX < e ? INT_MAX : e);
65   else
66     {
67       double r = x;
68
69       if (r != 0)
70         {
71           if (e < 0)
72             {
73               while (e++ != 0)
74                 {
75                   r /= radix;
76                   if (r == 0 && x != 0)
77                     {
78                       errno = ERANGE;
79                       break;
80                     }
81                 }
82             }
83           else
84             {
85               while (e-- != 0)
86                 {
87                   if (r < -DBL_MAX / radix)
88                     {
89                       errno = ERANGE;
90                       return -HUGE_VAL;
91                     }
92                   else if (DBL_MAX / radix < r)
93                     {
94                       errno = ERANGE;
95                       return HUGE_VAL;
96                     }
97                   else
98                     r *= radix;
99                 }
100             }
101         }
102
103       return r;
104     }
105 }
106
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).  */
113 static double
114 parse_number (const char *nptr,
115               int base, int radix, int radix_multiplier, char expchar,
116               char **endptr)
117 {
118   const char *s = nptr;
119   bool got_dot = false;
120   long int exponent = 0;
121   double num = 0;
122
123   for (;; ++s)
124     {
125       int digit;
126       if (c_isdigit (*s))
127         digit = *s - '0';
128       else if (base == 16 && c_isxdigit (*s))
129         digit = c_tolower (*s) - ('a' - 10);
130       else if (! got_dot && *s == '.')
131         {
132           /* Record that we have found the decimal point.  */
133           got_dot = true;
134           continue;
135         }
136       else
137         /* Any other character terminates the number.  */
138         break;
139
140       /* Make sure that multiplication by base will not overflow.  */
141       if (num <= DBL_MAX / base)
142         num = num * base + digit;
143       else
144         {
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.
149
150              We just need to record that there was another
151              digit so that we can multiply by 10 later.  */
152           exponent += radix_multiplier;
153         }
154
155       /* Keep track of the number of digits after the decimal point.
156          If we just divided by base here, we might lose precision.  */
157       if (got_dot)
158         exponent -= radix_multiplier;
159     }
160
161   if (c_tolower (*s) == expchar && ! locale_isspace (s[1]))
162     {
163       /* Add any given exponent to the implicit one.  */
164       int save = errno;
165       char *end;
166       long int value = strtol (s + 1, &end, 10);
167       errno = save;
168
169       if (s + 1 != end)
170         {
171           /* Skip past the exponent, and add in the implicit exponent,
172              resulting in an extreme value on overflow.  */
173           s = end;
174           exponent =
175             (exponent < 0
176              ? (value < LONG_MIN - exponent ? LONG_MIN : exponent + value)
177              : (LONG_MAX - exponent < value ? LONG_MAX : exponent + value));
178         }
179     }
180
181   *endptr = (char *) s;
182   return scale_radix_exp (num, radix, exponent);
183 }
184
185 static double underlying_strtod (const char *, char **);
186
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.  */
189 double
190 strtod (const char *nptr, char **endptr)
191 {
192   bool negative = false;
193
194   /* The number so far.  */
195   double num;
196
197   const char *s = nptr;
198   char *end;
199
200   /* Eat whitespace.  */
201   while (locale_isspace (*s))
202     ++s;
203
204   /* Get the sign.  */
205   negative = *s == '-';
206   if (*s == '-' || *s == '+')
207     ++s;
208
209   num = underlying_strtod (s, &end);
210
211   if (c_isdigit (s[*s == '.']))
212     {
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);
217
218       s = end;
219     }
220
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')
225     {
226       s += 3;
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')
232         s += 5;
233       num = HUGE_VAL;
234     }
235   else if (c_tolower (*s) == 'n'
236            && c_tolower (s[1]) == 'a'
237            && c_tolower (s[2]) == 'n')
238     {
239       s += 3;
240       if (*s == '(')
241         {
242           const char *p = s + 1;
243           while (c_isalnum (*p))
244             p++;
245           if (*p == ')')
246             s = p + 1;
247         }
248
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.  */
254       if (s != end)
255         num = NAN;
256     }
257   else
258     {
259       /* No conversion could be performed.  */
260       errno = EINVAL;
261       s = nptr;
262     }
263
264   if (endptr != NULL)
265     *endptr = (char *) s;
266   return negative ? -num : num;
267 }
268
269 /* The "underlying" strtod implementation.  This must be defined
270    after strtod because it #undefs strtod.  */
271 static double
272 underlying_strtod (const char *nptr, char **endptr)
273 {
274   if (HAVE_RAW_DECL_STRTOD)
275     {
276       /* Prefer the native strtod if available.  Usually it should
277          work and it should give more-accurate results than our
278          approximation.  */
279       #undef strtod
280       return strtod (nptr, endptr);
281     }
282   else
283     {
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);
288     }
289 }