compiler/clib: Rename IoErr2errno() to __arosc_ioerr2errno(); function is now defined...
[AROS.git] / compiler / clib / strtod.c
blob5fafe7a3410b1d8e97c82f2dd37cc59e7e8e95bc
1 /*
2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 $Id$
5 ANSI C function strtod().
6 */
8 #ifndef AROS_NOFPU
10 #include <ctype.h>
11 #include <errno.h>
12 #include <limits.h>
14 /*****************************************************************************
16 NAME */
17 #include <stdlib.h>
18 #include <math.h>
20 double strtod (
22 /* SYNOPSIS */
23 const char * str,
24 char ** endptr)
26 /* FUNCTION
27 Convert a string of digits into a double.
29 INPUTS
30 str - The string which should be converted. Leading
31 whitespace are ignored. The number may be prefixed
32 by a '+' or '-'. An 'e' or 'E' introduces the exponent.
33 Komma is only allowed before exponent.
34 endptr - If this is non-NULL, then the address of the first
35 character after the number in the string is stored
36 here.
38 RESULT
39 The value of the string. The first character after the number
40 is returned in *endptr, if endptr is non-NULL. If no digits can
41 be converted, *endptr contains str (if non-NULL) and 0 is
42 returned.
44 NOTES
46 EXAMPLE
48 BUGS
49 NAN is not handled at the moment
51 SEE ALSO
52 atof(), atoi(), atol(), strtol(), strtoul()
54 INTERNALS
56 ******************************************************************************/
58 /* Unit tests available in : tests/clib/strtod.c */
59 /* FIXME: implement NAN handling */
60 double val = 0, precision;
61 int exp = 0;
62 char c = 0, c2 = 0;
63 int digits = 0;
65 /* assign initial value in case nothing will be found */
66 if (endptr)
67 *endptr = (char *)str;
69 /* skip all leading spaces */
70 while (isspace (*str))
71 str ++;
73 /* start with scanning the floting point number */
74 if (*str)
76 /* Is there a sign? */
77 if (*str == '+' || *str == '-')
78 c = *str ++;
80 /* scan numbers before the dot */
81 while (isdigit(*str))
83 digits++;
84 val = val * 10 + (*str - '0');
85 str ++;
88 /* see if there is the dot and there were digits before it or there is
89 at least one digit after it */
90 if ((*str == '.') && ((digits > 0) || (isdigit(*(str + 1)))))
92 str++;
93 /* scan the numbers behind the dot */
94 precision = 0.1;
95 while (isdigit (*str))
97 digits++;
98 val += ((*str - '0') * precision) ;
99 str ++;
100 precision = precision * 0.1;
104 /* look for a sequence like "E+10" or "e-22" if there were any digits up to now */
105 if ((digits > 0) && (tolower(*str) == 'e'))
107 int edigits = 0;
108 str++;
110 if (*str == '+' || *str == '-')
111 c2 = *str ++;
113 while (isdigit (*str))
115 edigits++;
116 exp = exp * 10 + (*str - '0');
117 str ++;
120 if (c2 == '-')
121 exp = -exp;
123 if (edigits == 0)
125 /* there were no digits after 'e' - rollback pointer */
126 str--; if (c2 != 0) str--;
129 val *= pow (10, exp);
132 if (c == '-')
133 val = -val;
135 if ((digits == 0) && (c != 0))
137 /* there were no digits but there was sign - rollback pointer */
138 str--;
142 /* something was found, assign the pointer value */
143 if (endptr && digits > 0)
144 *endptr = (char *)str;
146 return val;
147 } /* strtod */
149 #else
151 void strtod (const char * str,char ** endptr)
153 return;
156 #endif /* AROS_NOFPU */