os/persistentdata/persistentstorage/sqlite3api/TEST/TCL/tcldistribution/compat/strtod.c
First public contribution.
4 * Source code for the "strtod" library procedure.
6 * Copyright (c) 1988-1993 The Regents of the University of California.
7 * Copyright (c) 1994 Sun Microsystems, Inc.
9 * See the file "license.terms" for information on usage and redistribution
10 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
12 * RCS: @(#) $Id: strtod.c,v 1.6 2002/02/25 14:26:12 dgp Exp $
27 static int maxExponent = 511; /* Largest possible base 10 exponent. Any
28 * exponent larger than this will already
29 * produce underflow or overflow, so there's
30 * no need to worry about additional digits.
32 static double powersOf10[] = { /* Table giving binary powers of 10. Entry */
33 10., /* is 10^2^i. Used to convert decimal */
34 100., /* exponents into floating-point numbers. */
45 *----------------------------------------------------------------------
49 * This procedure converts a floating-point number from an ASCII
50 * decimal representation to internal double-precision format.
53 * The return value is the double-precision floating-point
54 * representation of the characters in string. If endPtr isn't
55 * NULL, then *endPtr is filled in with the address of the
56 * next character after the last one that was part of the
57 * floating-point number.
62 *----------------------------------------------------------------------
66 strtod(string, endPtr)
67 CONST char *string; /* A decimal ASCII floating-point number,
68 * optionally preceded by white space.
69 * Must have form "-I.FE-X", where I is the
70 * integer part of the mantissa, F is the
71 * fractional part of the mantissa, and X
72 * is the exponent. Either of the signs
73 * may be "+", "-", or omitted. Either I
74 * or F may be omitted, or both. The decimal
75 * point isn't necessary unless F is present.
76 * The "E" may actually be an "e". E and X
77 * may both be omitted (but not just one).
79 char **endPtr; /* If non-NULL, store terminating character's
82 int sign, expSign = FALSE;
83 double fraction, dblExp, *d;
84 register CONST char *p;
86 int exp = 0; /* Exponent read from "EX" field. */
87 int fracExp = 0; /* Exponent that derives from the fractional
88 * part. Under normal circumstatnces, it is
89 * the negative of the number of digits in F.
90 * However, if I is very long, the last digits
91 * of I get dropped (otherwise a long I with a
92 * large negative exponent could cause an
93 * unnecessary overflow on I alone). In this
94 * case, fracExp is incremented one for each
96 int mantSize; /* Number of digits in mantissa. */
97 int decPt; /* Number of mantissa digits BEFORE decimal
99 CONST char *pExp; /* Temporarily holds location of exponent
103 * Strip off leading blanks and check for a sign.
107 while (isspace(UCHAR(*p))) {
121 * Count the number of digits in the mantissa (including the decimal
122 * point), and also locate the decimal point.
126 for (mantSize = 0; ; mantSize += 1)
130 if ((c != '.') || (decPt >= 0)) {
139 * Now suck up the digits in the mantissa. Use two integers to
140 * collect 9 digits each (this is faster than using floating-point).
141 * If the mantissa has more than 18 digits, ignore the extras, since
142 * they can't affect the value anyway.
150 mantSize -= 1; /* One of the digits was the point. */
153 fracExp = decPt - 18;
156 fracExp = decPt - mantSize;
165 for ( ; mantSize > 9; mantSize -= 1)
173 frac1 = 10*frac1 + (c - '0');
176 for (; mantSize > 0; mantSize -= 1)
184 frac2 = 10*frac2 + (c - '0');
186 fraction = (1.0e9 * frac1) + frac2;
190 * Skim off the exponent.
194 if ((*p == 'E') || (*p == 'e')) {
205 if (!isdigit(UCHAR(*p))) {
209 while (isdigit(UCHAR(*p))) {
210 exp = exp * 10 + (*p - '0');
221 * Generate a floating-point number that represents the exponent.
222 * Do this by processing the exponent one bit at a time to combine
223 * many powers of 2 of 10. Then combine the exponent with the
233 if (exp > maxExponent) {
238 for (d = powersOf10; exp != 0; exp >>= 1, d += 1) {
250 if (endPtr != NULL) {
251 *endPtr = (char *) p;