Merge branch 'upstream' into stable
[gnulib.git] / lib / strtod.c
1 /* Copyright (C) 1991-1992, 1997, 1999, 2003, 2006, 2008-2009 Free
2    Software 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 /* Don't use __attribute__ __nonnull__ in this compilation unit.  Otherwise gcc
20    optimizes away the nptr == NULL test below.  */
21 #define _GL_ARG_NONNULL(params)
22
23 #include <stdlib.h>
24
25 #include <ctype.h>
26 #include <errno.h>
27 #include <float.h>
28 #include <math.h>
29 #include <stdbool.h>
30 #include <string.h>
31
32 #include "c-ctype.h"
33
34 /* Convert NPTR to a double.  If ENDPTR is not NULL, a pointer to the
35    character after the last one used in the number is put in *ENDPTR.  */
36 double
37 strtod (const char *nptr, char **endptr)
38 {
39   const unsigned char *s;
40   bool negative = false;
41
42   /* The number so far.  */
43   double num;
44
45   bool got_dot;                 /* Found a decimal point.  */
46   bool got_digit;               /* Seen any digits.  */
47   bool hex = false;             /* Look for hex float exponent.  */
48
49   /* The exponent of the number.  */
50   long int exponent;
51
52   if (nptr == NULL)
53     {
54       errno = EINVAL;
55       goto noconv;
56     }
57
58   /* Use unsigned char for the ctype routines.  */
59   s = (unsigned char *) nptr;
60
61   /* Eat whitespace.  */
62   while (isspace (*s))
63     ++s;
64
65   /* Get the sign.  */
66   negative = *s == '-';
67   if (*s == '-' || *s == '+')
68     ++s;
69
70   num = 0.0;
71   got_dot = false;
72   got_digit = false;
73   exponent = 0;
74
75   /* Check for hex float.  */
76   if (*s == '0' && c_tolower (s[1]) == 'x'
77       && (c_isxdigit (s[2]) || ('.' == s[2] && c_isxdigit (s[3]))))
78     {
79       hex = true;
80       s += 2;
81       for (;; ++s)
82         {
83           if (c_isxdigit (*s))
84             {
85               got_digit = true;
86
87               /* Make sure that multiplication by 16 will not overflow.  */
88               if (num > DBL_MAX / 16)
89                 /* The value of the digit doesn't matter, since we have already
90                    gotten as many digits as can be represented in a `double'.
91                    This doesn't necessarily mean the result will overflow.
92                    The exponent may reduce it to within range.
93
94                    We just need to record that there was another
95                    digit so that we can multiply by 16 later.  */
96                 ++exponent;
97               else
98                 num = ((num * 16.0)
99                        + (c_tolower (*s) - (c_isdigit (*s) ? '0' : 'a' - 10)));
100
101               /* Keep track of the number of digits after the decimal point.
102                  If we just divided by 16 here, we would lose precision.  */
103               if (got_dot)
104                 --exponent;
105             }
106           else if (!got_dot && *s == '.')
107             /* Record that we have found the decimal point.  */
108             got_dot = true;
109           else
110             /* Any other character terminates the number.  */
111             break;
112         }
113     }
114
115   /* Not a hex float.  */
116   else
117     {
118       for (;; ++s)
119         {
120           if (c_isdigit (*s))
121             {
122               got_digit = true;
123
124               /* Make sure that multiplication by 10 will not overflow.  */
125               if (num > DBL_MAX * 0.1)
126                 /* The value of the digit doesn't matter, since we have already
127                    gotten as many digits as can be represented in a `double'.
128                    This doesn't necessarily mean the result will overflow.
129                    The exponent may reduce it to within range.
130
131                    We just need to record that there was another
132                    digit so that we can multiply by 10 later.  */
133                 ++exponent;
134               else
135                 num = (num * 10.0) + (*s - '0');
136
137               /* Keep track of the number of digits after the decimal point.
138                  If we just divided by 10 here, we would lose precision.  */
139               if (got_dot)
140                 --exponent;
141             }
142           else if (!got_dot && *s == '.')
143             /* Record that we have found the decimal point.  */
144             got_dot = true;
145           else
146             /* Any other character terminates the number.  */
147             break;
148         }
149     }
150
151   if (!got_digit)
152     {
153       /* Check for infinities and NaNs.  */
154       if (c_tolower (*s) == 'i'
155           && c_tolower (s[1]) == 'n'
156           && c_tolower (s[2]) == 'f')
157         {
158           s += 3;
159           num = HUGE_VAL;
160           if (c_tolower (*s) == 'i'
161               && c_tolower (s[1]) == 'n'
162               && c_tolower (s[2]) == 'i'
163               && c_tolower (s[3]) == 't'
164               && c_tolower (s[4]) == 'y')
165             s += 5;
166           goto valid;
167         }
168 #ifdef NAN
169       else if (c_tolower (*s) == 'n'
170                && c_tolower (s[1]) == 'a'
171                && c_tolower (s[2]) == 'n')
172         {
173           s += 3;
174           num = NAN;
175           /* Since nan(<n-char-sequence>) is implementation-defined,
176              we define it by ignoring <n-char-sequence>.  A nicer
177              implementation would populate the bits of the NaN
178              according to interpreting n-char-sequence as a
179              hexadecimal number, but the result is still a NaN.  */
180           if (*s == '(')
181             {
182               const unsigned char *p = s + 1;
183               while (c_isalnum (*p))
184                 p++;
185               if (*p == ')')
186                 s = p + 1;
187             }
188           goto valid;
189         }
190 #endif
191       goto noconv;
192     }
193
194   if (c_tolower (*s) == (hex ? 'p' : 'e') && !isspace (s[1]))
195     {
196       /* Get the exponent specified after the `e' or `E'.  */
197       int save = errno;
198       char *end;
199       long int value;
200
201       errno = 0;
202       ++s;
203       value = strtol ((char *) s, &end, 10);
204       if (errno == ERANGE && num)
205         {
206           /* The exponent overflowed a `long int'.  It is probably a safe
207              assumption that an exponent that cannot be represented by
208              a `long int' exceeds the limits of a `double'.  */
209           if (endptr != NULL)
210             *endptr = end;
211           if (value < 0)
212             goto underflow;
213           else
214             goto overflow;
215         }
216       else if (end == (char *) s)
217         /* There was no exponent.  Reset END to point to
218            the 'e' or 'E', so *ENDPTR will be set there.  */
219         end = (char *) s - 1;
220       errno = save;
221       s = (unsigned char *) end;
222       exponent += value;
223     }
224
225   if (num == 0.0)
226     goto valid;
227
228   if (hex)
229     {
230       /* ldexp takes care of range errors.  */
231       num = ldexp (num, exponent);
232       goto valid;
233     }
234
235   /* Multiply NUM by 10 to the EXPONENT power,
236      checking for overflow and underflow.  */
237
238   if (exponent < 0)
239     {
240       if (num < DBL_MIN * pow (10.0, (double) -exponent))
241         goto underflow;
242     }
243   else if (exponent > 0)
244     {
245       if (num > DBL_MAX * pow (10.0, (double) -exponent))
246         goto overflow;
247     }
248
249   num *= pow (10.0, (double) exponent);
250
251  valid:
252   if (endptr != NULL)
253     *endptr = (char *) s;
254   return negative ? -num : num;
255
256  overflow:
257   /* Return an overflow error.  */
258   if (endptr != NULL)
259     *endptr = (char *) s;
260   errno = ERANGE;
261   return negative ? -HUGE_VAL : HUGE_VAL;
262
263  underflow:
264   /* Return an underflow error.  */
265   if (endptr != NULL)
266     *endptr = (char *) s;
267   errno = ERANGE;
268   return negative ? -0.0 : 0.0;
269
270  noconv:
271   /* There was no number.  */
272   if (endptr != NULL)
273     *endptr = (char *) nptr;
274   errno = EINVAL;
275   return 0.0;
276 }