Rename module 'memxfrm' to 'amemxfrm'.
[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   const char *end;
204   char *endbuf;
205
206   /* Eat whitespace.  */
207   while (locale_isspace (*s))
208     ++s;
209
210   /* Get the sign.  */
211   negative = *s == '-';
212   if (*s == '-' || *s == '+')
213     ++s;
214
215   num = underlying_strtod (s, &endbuf);
216   end = endbuf;
217
218   if (c_isdigit (s[*s == '.']))
219     {
220       /* If a hex float was converted incorrectly, do it ourselves.
221          If the string starts with "0x" but does not contain digits,
222          consume the "0" ourselves.  If a hex float is followed by a
223          'p' but no exponent, then adjust the end pointer.  */
224       if (*s == '0' && c_tolower (s[1]) == 'x')
225         {
226           if (! c_isxdigit (s[2 + (s[2] == '.')]))
227             end = s + 1;
228           else if (end <= s + 2)
229             {
230               num = parse_number (s + 2, 16, 2, 4, 'p', &endbuf);
231               end = endbuf;
232             }
233           else
234             {
235               const char *p = s + 2;
236               while (p < end && c_tolower (*p) != 'p')
237                 p++;
238               if (p < end && ! c_isdigit (p[1 + (p[1] == '-' || p[1] == '+')]))
239                 end = p;
240             }
241         }
242
243       s = end;
244     }
245
246   /* Check for infinities and NaNs.  */
247   else if (c_tolower (*s) == 'i'
248            && c_tolower (s[1]) == 'n'
249            && c_tolower (s[2]) == 'f')
250     {
251       s += 3;
252       if (c_tolower (*s) == 'i'
253           && c_tolower (s[1]) == 'n'
254           && c_tolower (s[2]) == 'i'
255           && c_tolower (s[3]) == 't'
256           && c_tolower (s[4]) == 'y')
257         s += 5;
258       num = HUGE_VAL;
259     }
260   else if (c_tolower (*s) == 'n'
261            && c_tolower (s[1]) == 'a'
262            && c_tolower (s[2]) == 'n')
263     {
264       s += 3;
265       if (*s == '(')
266         {
267           const char *p = s + 1;
268           while (c_isalnum (*p))
269             p++;
270           if (*p == ')')
271             s = p + 1;
272         }
273
274       /* If the underlying implementation misparsed the NaN, assume
275          its result is incorrect, and return a NaN.  Normally it's
276          better to use the underlying implementation's result, since a
277          nice implementation populates the bits of the NaN according
278          to interpreting n-char-sequence as a hexadecimal number.  */
279       if (s != end)
280         num = NAN;
281     }
282   else
283     {
284       /* No conversion could be performed.  */
285       errno = EINVAL;
286       s = nptr;
287     }
288
289   if (endptr != NULL)
290     *endptr = (char *) s;
291   return negative ? -num : num;
292 }
293
294 /* The "underlying" strtod implementation.  This must be defined
295    after strtod because it #undefs strtod.  */
296 static double
297 underlying_strtod (const char *nptr, char **endptr)
298 {
299   if (HAVE_RAW_DECL_STRTOD)
300     {
301       /* Prefer the native strtod if available.  Usually it should
302          work and it should give more-accurate results than our
303          approximation.  */
304       #undef strtod
305       return strtod (nptr, endptr);
306     }
307   else
308     {
309       /* Approximate strtod well enough for this module.  There's no
310          need to handle anything but finite unsigned decimal
311          numbers with nonnull ENDPTR.  */
312       return parse_number (nptr, 10, 10, 1, 'e', endptr);
313     }
314 }