1.1.5
by akira yamada
Import upstream version 1.8.6 |
1 |
/*
|
2 |
* strtod.c --
|
|
3 |
*
|
|
4 |
* Source code for the "strtod" library procedure.
|
|
5 |
*
|
|
6 |
* Copyright (c) 1988-1993 The Regents of the University of California.
|
|
7 |
* Copyright (c) 1994 Sun Microsystems, Inc.
|
|
8 |
*
|
|
9 |
* Permission to use, copy, modify, and distribute this
|
|
10 |
* software and its documentation for any purpose and without
|
|
11 |
* fee is hereby granted, provided that the above copyright
|
|
12 |
* notice appear in all copies. The University of California
|
|
13 |
* makes no representations about the suitability of this
|
|
14 |
* software for any purpose. It is provided "as is" without
|
|
15 |
* express or implied warranty.
|
|
16 |
*
|
|
17 |
* RCS: @(#) $Id: strtod.c 11708 2007-02-12 23:01:19Z shyouhei $
|
|
18 |
*/
|
|
19 |
||
20 |
#include "config.h" |
|
21 |
#ifdef HAVE_STDLIB_H
|
|
22 |
# include <stdlib.h>
|
|
23 |
#endif
|
|
24 |
#include <ctype.h> |
|
25 |
#include <errno.h> |
|
26 |
extern int errno; |
|
27 |
||
28 |
#ifndef __STDC__
|
|
29 |
# ifdef __GNUC__
|
|
30 |
# define const __const__
|
|
31 |
# else
|
|
32 |
# define const
|
|
33 |
# endif
|
|
34 |
#endif
|
|
35 |
||
36 |
#ifndef TRUE
|
|
37 |
#define TRUE 1
|
|
38 |
#define FALSE 0
|
|
39 |
#endif
|
|
40 |
#ifndef NULL
|
|
41 |
#define NULL 0
|
|
42 |
#endif
|
|
43 |
||
44 |
static int maxExponent = 511; /* Largest possible base 10 exponent. Any |
|
45 |
* exponent larger than this will already
|
|
46 |
* produce underflow or overflow, so there's
|
|
47 |
* no need to worry about additional digits.
|
|
48 |
*/
|
|
49 |
static double powersOf10[] = { /* Table giving binary powers of 10. Entry */ |
|
50 |
10., /* is 10^2^i. Used to convert decimal */ |
|
51 |
100., /* exponents into floating-point numbers. */ |
|
52 |
1.0e4, |
|
53 |
1.0e8, |
|
54 |
1.0e16, |
|
55 |
1.0e32, |
|
56 |
1.0e64, |
|
57 |
1.0e128, |
|
58 |
1.0e256
|
|
59 |
};
|
|
60 |
||
61 |
/*
|
|
62 |
*----------------------------------------------------------------------
|
|
63 |
*
|
|
64 |
* strtod --
|
|
65 |
*
|
|
66 |
* This procedure converts a floating-point number from an ASCII
|
|
67 |
* decimal representation to internal double-precision format.
|
|
68 |
*
|
|
69 |
* Results:
|
|
70 |
* The return value is the double-precision floating-point
|
|
71 |
* representation of the characters in string. If endPtr isn't
|
|
72 |
* NULL, then *endPtr is filled in with the address of the
|
|
73 |
* next character after the last one that was part of the
|
|
74 |
* floating-point number.
|
|
75 |
*
|
|
76 |
* Side effects:
|
|
77 |
* None.
|
|
78 |
*
|
|
79 |
*----------------------------------------------------------------------
|
|
80 |
*/
|
|
81 |
||
82 |
double
|
|
83 |
strtod(string, endPtr) |
|
84 |
const char *string; /* A decimal ASCII floating-point number, |
|
85 |
* optionally preceded by white space.
|
|
86 |
* Must have form "-I.FE-X", where I is the
|
|
87 |
* integer part of the mantissa, F is the
|
|
88 |
* fractional part of the mantissa, and X
|
|
89 |
* is the exponent. Either of the signs
|
|
90 |
* may be "+", "-", or omitted. Either I
|
|
91 |
* or F may be omitted, or both. The decimal
|
|
92 |
* point isn't necessary unless F is present.
|
|
93 |
* The "E" may actually be an "e". E and X
|
|
94 |
* may both be omitted (but not just one).
|
|
95 |
*/
|
|
96 |
char **endPtr; /* If non-NULL, store terminating character's |
|
97 |
* address here. */
|
|
98 |
{
|
|
99 |
int sign, expSign = FALSE; |
|
100 |
double fraction, dblExp, *d; |
|
101 |
register const char *p; |
|
102 |
register int c; |
|
103 |
int exp = 0; /* Exponent read from "EX" field. */ |
|
104 |
int fracExp = 0; /* Exponent that derives from the fractional |
|
105 |
* part. Under normal circumstatnces, it is
|
|
106 |
* the negative of the number of digits in F.
|
|
107 |
* However, if I is very long, the last digits
|
|
108 |
* of I get dropped (otherwise a long I with a
|
|
109 |
* large negative exponent could cause an
|
|
110 |
* unnecessary overflow on I alone). In this
|
|
111 |
* case, fracExp is incremented one for each
|
|
112 |
* dropped digit. */
|
|
113 |
int mantSize; /* Number of digits in mantissa. */ |
|
114 |
int decPt; /* Number of mantissa digits BEFORE decimal |
|
115 |
* point. */
|
|
116 |
const char *pExp; /* Temporarily holds location of exponent |
|
117 |
* in string. */
|
|
118 |
||
119 |
/*
|
|
120 |
* Strip off leading blanks and check for a sign.
|
|
121 |
*/
|
|
122 |
||
123 |
p = string; |
|
124 |
while (isspace(*p)) { |
|
125 |
p += 1; |
|
126 |
}
|
|
127 |
if (*p == '-') { |
|
128 |
sign = TRUE; |
|
129 |
p += 1; |
|
130 |
} else { |
|
131 |
if (*p == '+') { |
|
132 |
p += 1; |
|
133 |
}
|
|
134 |
sign = FALSE; |
|
135 |
}
|
|
136 |
||
137 |
/*
|
|
138 |
* Count the number of digits in the mantissa (including the decimal
|
|
139 |
* point), and also locate the decimal point.
|
|
140 |
*/
|
|
141 |
||
142 |
decPt = -1; |
|
143 |
for (mantSize = 0; ; mantSize += 1) |
|
144 |
{
|
|
145 |
c = *p; |
|
146 |
if (!isdigit(c)) { |
|
147 |
if ((c != '.') || (decPt >= 0)) { |
|
148 |
break; |
|
149 |
}
|
|
150 |
decPt = mantSize; |
|
151 |
}
|
|
152 |
p += 1; |
|
153 |
}
|
|
154 |
||
155 |
/*
|
|
156 |
* Now suck up the digits in the mantissa. Use two integers to
|
|
157 |
* collect 9 digits each (this is faster than using floating-point).
|
|
158 |
* If the mantissa has more than 18 digits, ignore the extras, since
|
|
159 |
* they can't affect the value anyway.
|
|
160 |
*/
|
|
161 |
||
162 |
pExp = p; |
|
163 |
p -= mantSize; |
|
164 |
if (decPt < 0) { |
|
165 |
decPt = mantSize; |
|
166 |
} else { |
|
167 |
mantSize -= 1; /* One of the digits was the point. */ |
|
168 |
}
|
|
169 |
if (mantSize > 18) { |
|
170 |
fracExp = decPt - 18; |
|
171 |
mantSize = 18; |
|
172 |
} else { |
|
173 |
fracExp = decPt - mantSize; |
|
174 |
}
|
|
175 |
if (mantSize == 0) { |
|
176 |
fraction = 0.0; |
|
177 |
p = string; |
|
178 |
goto done; |
|
179 |
} else { |
|
180 |
int frac1, frac2; |
|
181 |
frac1 = 0; |
|
182 |
for ( ; mantSize > 9; mantSize -= 1) |
|
183 |
{
|
|
184 |
c = *p; |
|
185 |
p += 1; |
|
186 |
if (c == '.') { |
|
187 |
c = *p; |
|
188 |
p += 1; |
|
189 |
}
|
|
190 |
frac1 = 10*frac1 + (c - '0'); |
|
191 |
}
|
|
192 |
frac2 = 0; |
|
193 |
for (; mantSize > 0; mantSize -= 1) |
|
194 |
{
|
|
195 |
c = *p; |
|
196 |
p += 1; |
|
197 |
if (c == '.') { |
|
198 |
c = *p; |
|
199 |
p += 1; |
|
200 |
}
|
|
201 |
frac2 = 10*frac2 + (c - '0'); |
|
202 |
}
|
|
203 |
fraction = (1.0e9 * frac1) + frac2; |
|
204 |
}
|
|
205 |
||
206 |
/*
|
|
207 |
* Skim off the exponent.
|
|
208 |
*/
|
|
209 |
||
210 |
p = pExp; |
|
211 |
if ((*p == 'E') || (*p == 'e')) { |
|
212 |
p += 1; |
|
213 |
if (*p == '-') { |
|
214 |
expSign = TRUE; |
|
215 |
p += 1; |
|
216 |
} else { |
|
217 |
if (*p == '+') { |
|
218 |
p += 1; |
|
219 |
}
|
|
220 |
expSign = FALSE; |
|
221 |
}
|
|
222 |
while (isdigit(*p)) { |
|
223 |
exp = exp * 10 + (*p - '0'); |
|
224 |
p += 1; |
|
225 |
}
|
|
226 |
}
|
|
227 |
if (expSign) { |
|
228 |
exp = fracExp - exp; |
|
229 |
} else { |
|
230 |
exp = fracExp + exp; |
|
231 |
}
|
|
232 |
||
233 |
/*
|
|
234 |
* Generate a floating-point number that represents the exponent.
|
|
235 |
* Do this by processing the exponent one bit at a time to combine
|
|
236 |
* many powers of 2 of 10. Then combine the exponent with the
|
|
237 |
* fraction.
|
|
238 |
*/
|
|
239 |
||
240 |
if (exp < 0) { |
|
241 |
expSign = TRUE; |
|
242 |
exp = -exp; |
|
243 |
} else { |
|
244 |
expSign = FALSE; |
|
245 |
}
|
|
246 |
if (exp > maxExponent) { |
|
247 |
exp = maxExponent; |
|
248 |
errno = ERANGE; |
|
249 |
}
|
|
250 |
dblExp = 1.0; |
|
251 |
for (d = powersOf10; exp != 0; exp >>= 1, d += 1) { |
|
252 |
if (exp & 01) { |
|
253 |
dblExp *= *d; |
|
254 |
}
|
|
255 |
}
|
|
256 |
if (expSign) { |
|
257 |
fraction /= dblExp; |
|
258 |
} else { |
|
259 |
fraction *= dblExp; |
|
260 |
}
|
|
261 |
||
262 |
done: |
|
263 |
if (endPtr != NULL) { |
|
264 |
*endPtr = (char *) p; |
|
265 |
}
|
|
266 |
||
267 |
if (sign) { |
|
268 |
return -fraction; |
|
269 |
}
|
|
270 |
return fraction; |
|
271 |
}
|