2 * This strtod has been modified to not use values from the locale,
3 * but to hardcode the `.' as the separator. Our class libraries will
4 * make sure that only the dot is passed.
6 * This is so we do not call `setlocale' from our runtime before doing
7 * a strtod, because this could have unwanted effects in code that is
8 * co-hosted with the Mono runtime
10 * The entry point has been renamed `bsd_strtod'.
12 * Taken from the TclTk distribution 8.4.13
17 * Source code for the "strtod" library procedure.
19 * Copyright (c) 1988-1993 The Regents of the University of California.
20 * Copyright (c) 1994 Sun Microsystems, Inc.
22 * See the file "license.terms" for information on usage and redistribution
23 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
25 * RCS: @(#) Id: strtod.c,v 1.1 2006/05/06 18:21:43 barre Exp
32 #define UCHAR(x) ((unsigned char) (x))
42 static const int maxExponent = 511; /* Largest possible base 10 exponent. Any
43 * exponent larger than this will already
44 * produce underflow or overflow, so there's
45 * no need to worry about additional digits.
47 static const double powersOf10[] = { /* Table giving binary powers of 10. Entry */
48 10., /* is 10^2^i. Used to convert decimal */
49 100., /* exponents into floating-point numbers. */
60 *----------------------------------------------------------------------
64 * This procedure converts a floating-point number from an ASCII
65 * decimal representation to internal double-precision format.
68 * The return value is the double-precision floating-point
69 * representation of the characters in string. If endPtr isn't
70 * NULL, then *endPtr is filled in with the address of the
71 * next character after the last one that was part of the
72 * floating-point number.
77 *----------------------------------------------------------------------
81 bsd_strtod(const char *string, char **endPtr)
82 /* string: A decimal ASCII floating-point number,
83 * optionally preceded by white space.
84 * Must have form "-I.FE-X", where I is the
85 * integer part of the mantissa, F is the
86 * fractional part of the mantissa, and X
87 * is the exponent. Either of the signs
88 * may be "+", "-", or omitted. Either I
89 * or F may be omitted, or both. The decimal
90 * point isn't necessary unless F is present.
91 * The "E" may actually be an "e". E and X
92 * may both be omitted (but not just one).
94 /* endPtr: If non-NULL, store terminating character's
97 int sign, expSign = FALSE;
98 double fraction, dblExp;
100 register const char *p;
102 int exp = 0; /* Exponent read from "EX" field. */
103 int fracExp = 0; /* Exponent that derives from the fractional
104 * part. Under normal circumstatnces, it is
105 * the negative of the number of digits in F.
106 * However, if I is very long, the last digits
107 * of I get dropped (otherwise a long I with a
108 * large negative exponent could cause an
109 * unnecessary overflow on I alone). In this
110 * case, fracExp is incremented one for each
112 int mantSize; /* Number of digits in mantissa. */
113 int decPt; /* Number of mantissa digits BEFORE decimal
115 const char *pExp; /* Temporarily holds location of exponent
119 * Strip off leading blanks and check for a sign.
123 while (isspace(UCHAR(*p))) {
137 * Count the number of digits in the mantissa (including the decimal
138 * point), and also locate the decimal point.
142 for (mantSize = 0; ; mantSize += 1)
146 if ((c != '.') || (decPt >= 0)) {
155 * Now suck up the digits in the mantissa. Use two integers to
156 * collect 9 digits each (this is faster than using floating-point).
157 * If the mantissa has more than 18 digits, ignore the extras, since
158 * they can't affect the value anyway.
166 mantSize -= 1; /* One of the digits was the point. */
169 fracExp = decPt - 18;
172 fracExp = decPt - mantSize;
181 for ( ; mantSize > 9; mantSize -= 1)
189 frac1 = 10*frac1 + (c - '0');
192 for (; mantSize > 0; mantSize -= 1)
200 frac2 = 10*frac2 + (c - '0');
202 fraction = (1.0e9 * frac1) + frac2;
206 * Skim off the exponent.
210 if ((*p == 'E') || (*p == 'e')) {
221 if (!isdigit(UCHAR(*p))) {
225 while (isdigit(UCHAR(*p))) {
226 exp = exp * 10 + (*p - '0');
237 * Generate a floating-point number that represents the exponent.
238 * Do this by processing the exponent one bit at a time to combine
239 * many powers of 2 of 10. Then combine the exponent with the
249 if (exp > maxExponent) {
254 for (d = powersOf10; exp != 0; exp >>= 1, d += 1) {
266 if (endPtr != NULL) {
267 *endPtr = (char *) p;