83b858ae5e7cb23f0c4b1d1bb2ae1263b497be04
[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  /* A dummy definition that will never be invoked.  */
49  static double ldexp (double x _GL_UNUSED, int exponent _GL_UNUSED)
50  {
51    abort ();
52    return 0.0;
53  }
54 #endif
55
56 /* Return X * BASE**EXPONENT.  Return an extreme value and set errno
57    to ERANGE if underflow or overflow occurs.  */
58 static double
59 scale_radix_exp (double x, int radix, long int exponent)
60 {
61   /* If RADIX == 10, this code is neither precise nor fast; it is
62      merely a straightforward and relatively portable approximation.
63      If N == 2, this code is precise on a radix-2 implementation,
64      albeit perhaps not fast if ldexp is not in libc.  */
65
66   long int e = exponent;
67
68   if (HAVE_LDEXP_IN_LIBC && radix == 2)
69     return ldexp (x, e < INT_MIN ? INT_MIN : INT_MAX < e ? INT_MAX : e);
70   else
71     {
72       double r = x;
73
74       if (r != 0)
75         {
76           if (e < 0)
77             {
78               while (e++ != 0)
79                 {
80                   r /= radix;
81                   if (r == 0 && x != 0)
82                     {
83                       errno = ERANGE;
84                       break;
85                     }
86                 }
87             }
88           else
89             {
90               while (e-- != 0)
91                 {
92                   if (r < -DBL_MAX / radix)
93                     {
94                       errno = ERANGE;
95                       return -HUGE_VAL;
96                     }
97                   else if (DBL_MAX / radix < r)
98                     {
99                       errno = ERANGE;
100                       return HUGE_VAL;
101                     }
102                   else
103                     r *= radix;
104                 }
105             }
106         }
107
108       return r;
109     }
110 }
111
112 /* Parse a number at NPTR; this is a bit like strtol (NPTR, ENDPTR)
113    except there are no leading spaces or signs or "0x", and ENDPTR is
114    nonnull.  The number uses a base BASE (either 10 or 16) fraction, a
115    radix RADIX (either 10 or 2) exponent, and exponent character
116    EXPCHAR.  To convert from a number of digits to a radix exponent,
117    multiply by RADIX_MULTIPLIER (either 1 or 4).  */
118 static double
119 parse_number (const char *nptr,
120               int base, int radix, int radix_multiplier, char expchar,
121               char **endptr)
122 {
123   const char *s = nptr;
124   bool got_dot = false;
125   long int exponent = 0;
126   double num = 0;
127
128   for (;; ++s)
129     {
130       int digit;
131       if (c_isdigit (*s))
132         digit = *s - '0';
133       else if (base == 16 && c_isxdigit (*s))
134         digit = c_tolower (*s) - ('a' - 10);
135       else if (! got_dot && *s == '.')
136         {
137           /* Record that we have found the decimal point.  */
138           got_dot = true;
139           continue;
140         }
141       else
142         /* Any other character terminates the number.  */
143         break;
144
145       /* Make sure that multiplication by base will not overflow.  */
146       if (num <= DBL_MAX / base)
147         num = num * base + digit;
148       else
149         {
150           /* The value of the digit doesn't matter, since we have already
151              gotten as many digits as can be represented in a `double'.
152              This doesn't necessarily mean the result will overflow.
153              The exponent may reduce it to within range.
154
155              We just need to record that there was another
156              digit so that we can multiply by 10 later.  */
157           exponent += radix_multiplier;
158         }
159
160       /* Keep track of the number of digits after the decimal point.
161          If we just divided by base here, we might lose precision.  */
162       if (got_dot)
163         exponent -= radix_multiplier;
164     }
165
166   if (c_tolower (*s) == expchar && ! locale_isspace (s[1]))
167     {
168       /* Add any given exponent to the implicit one.  */
169       int save = errno;
170       char *end;
171       long int value = strtol (s + 1, &end, 10);
172       errno = save;
173
174       if (s + 1 != end)
175         {
176           /* Skip past the exponent, and add in the implicit exponent,
177              resulting in an extreme value on overflow.  */
178           s = end;
179           exponent =
180             (exponent < 0
181              ? (value < LONG_MIN - exponent ? LONG_MIN : exponent + value)
182              : (LONG_MAX - exponent < value ? LONG_MAX : exponent + value));
183         }
184     }
185
186   *endptr = (char *) s;
187   return scale_radix_exp (num, radix, exponent);
188 }
189
190 static double underlying_strtod (const char *, char **);
191
192 /* Convert NPTR to a double.  If ENDPTR is not NULL, a pointer to the
193    character after the last one used in the number is put in *ENDPTR.  */
194 double
195 strtod (const char *nptr, char **endptr)
196 {
197   bool negative = false;
198
199   /* The number so far.  */
200   double num;
201
202   const char *s = nptr;
203   char *end;
204
205   /* Eat whitespace.  */
206   while (locale_isspace (*s))
207     ++s;
208
209   /* Get the sign.  */
210   negative = *s == '-';
211   if (*s == '-' || *s == '+')
212     ++s;
213
214   num = underlying_strtod (s, &end);
215
216   if (c_isdigit (s[*s == '.']))
217     {
218       /* If a hex float was converted incorrectly, do it ourselves.  */
219       if (*s == '0' && c_tolower (s[1]) == 'x' && end <= s + 2
220           && c_isxdigit (s[2 + (s[2] == '.')]))
221         num = parse_number (s + 2, 16, 2, 4, 'p', &end);
222
223       s = end;
224     }
225
226   /* Check for infinities and NaNs.  */
227   else if (c_tolower (*s) == 'i'
228            && c_tolower (s[1]) == 'n'
229            && c_tolower (s[2]) == 'f')
230     {
231       s += 3;
232       if (c_tolower (*s) == 'i'
233           && c_tolower (s[1]) == 'n'
234           && c_tolower (s[2]) == 'i'
235           && c_tolower (s[3]) == 't'
236           && c_tolower (s[4]) == 'y')
237         s += 5;
238       num = HUGE_VAL;
239     }
240   else if (c_tolower (*s) == 'n'
241            && c_tolower (s[1]) == 'a'
242            && c_tolower (s[2]) == 'n')
243     {
244       s += 3;
245       if (*s == '(')
246         {
247           const char *p = s + 1;
248           while (c_isalnum (*p))
249             p++;
250           if (*p == ')')
251             s = p + 1;
252         }
253
254       /* If the underlying implementation misparsed the NaN, assume
255          its result is incorrect, and return a NaN.  Normally it's
256          better to use the underlying implementation's result, since a
257          nice implementation populates the bits of the NaN according
258          to interpreting n-char-sequence as a hexadecimal number.  */
259       if (s != end)
260         num = NAN;
261     }
262   else
263     {
264       /* No conversion could be performed.  */
265       errno = EINVAL;
266       s = nptr;
267     }
268
269   if (endptr != NULL)
270     *endptr = (char *) s;
271   return negative ? -num : num;
272 }
273
274 /* The "underlying" strtod implementation.  This must be defined
275    after strtod because it #undefs strtod.  */
276 static double
277 underlying_strtod (const char *nptr, char **endptr)
278 {
279   if (HAVE_RAW_DECL_STRTOD)
280     {
281       /* Prefer the native strtod if available.  Usually it should
282          work and it should give more-accurate results than our
283          approximation.  */
284       #undef strtod
285       return strtod (nptr, endptr);
286     }
287   else
288     {
289       /* Approximate strtod well enough for this module.  There's no
290          need to handle anything but finite unsigned decimal
291          numbers with nonnull ENDPTR.  */
292       return parse_number (nptr, 10, 10, 1, 'e', endptr);
293     }
294 }