]>
git.zerfleddert.de Git - micropolis/blob - src/tcl/compat/strtod.c
4 * Source code for the "strtod" library procedure.
6 * Copyright 1988-1992 Regents of the University of California
7 * Permission to use, copy, modify, and distribute this
8 * software and its documentation for any purpose and without
9 * fee is hereby granted, provided that the above copyright
10 * notice appear in all copies. The University of California
11 * makes no representations about the suitability of this
12 * software for any purpose. It is provided "as is" without
13 * express or implied warranty.
17 static char rcsid
[] = "$Header: /user6/ouster/tcl/compat/RCS/strtod.c,v 1.1 92/01/03 16:39:02 ouster Exp $ SPRITE (Berkeley)";
31 static int maxExponent
= 511; /* Largest possible base 10 exponent. Any
32 * exponent larger than this will already
33 * produce underflow or overflow, so there's
34 * no need to worry about additional digits.
36 static double powersOf10
[] = { /* Table giving binary powers of 10. Entry */
37 10., /* is 10^2^i. Used to convert decimal */
38 100., /* exponents into floating-point numbers. */
49 *----------------------------------------------------------------------
53 * This procedure converts a floating-point number from an ASCII
54 * decimal representation to internal double-precision format.
57 * The return value is the double-precision floating-point
58 * representation of the characters in string. If endPtr isn't
59 * NULL, then *endPtr is filled in with the address of the
60 * next character after the last one that was part of the
61 * floating-point number.
66 *----------------------------------------------------------------------
70 strtod(string
, endPtr
)
71 char *string
; /* A decimal ASCII floating-point number,
72 * optionally preceded by white space.
73 * Must have form "-I.FE-X", where I is the
74 * integer part of the mantissa, F is the
75 * fractional part of the mantissa, and X
76 * is the exponent. Either of the signs
77 * may be "+", "-", or omitted. Either I
78 * or F may be omitted, or both. The decimal
79 * point isn't necessary unless F is present.
80 * The "E" may actually be an "e". E and X
81 * may both be omitted (but not just one).
83 char **endPtr
; /* If non-NULL, store terminating character's
86 int sign
, expSign
= FALSE
;
87 double fraction
, dblExp
, *d
;
89 int exp
= 0; /* Exponent read from "EX" field. */
90 int fracExp
= 0; /* Exponent that derives from the fractional
91 * part. Under normal circumstatnces, it is
92 * the negative of the number of digits in F.
93 * However, if I is very long, the last digits
94 * of I get dropped (otherwise a long I with a
95 * large negative exponent could cause an
96 * unnecessary overflow on I alone). In this
97 * case, fracExp is incremented one for each
100 int mantSize
; /* Number of digits in mantissa. */
101 int decPt
; /* Number of mantissa digits BEFORE decimal
104 char *pExp
; /* Temporarily holds location of exponent
109 * Strip off leading blanks and check for a sign.
113 while (isspace(*p
)) {
127 * Count the number of digits in the mantissa (including the decimal
128 * point), and also locate the decimal point.
132 for (mantSize
= 0; ; mantSize
+= 1)
136 if ((c
!= '.') || (decPt
>= 0)) {
145 * Now suck up the digits in the mantissa. Use two integers to
146 * collect 9 digits each (this is faster than using floating-point).
147 * If the mantissa has more than 18 digits, ignore the extras, since
148 * they can't affect the value anyway.
156 mantSize
-= 1; /* One of the digits was the point. */
159 fracExp
= decPt
- 18;
162 fracExp
= decPt
- mantSize
;
171 for ( ; mantSize
> 9; mantSize
-= 1)
179 frac1
= 10*frac1
+ (c
- '0');
182 for (; mantSize
> 0; mantSize
-= 1)
190 frac2
= 10*frac2
+ (c
- '0');
192 fraction
= (1.0e9
* frac1
) + frac2
;
196 * Skim off the exponent.
200 if ((*p
== 'E') || (*p
== 'e')) {
211 while (isdigit(*p
)) {
212 exp
= exp
* 10 + (*p
- '0');
223 * Generate a floating-point number that represents the exponent.
224 * Do this by processing the exponent one bit at a time to combine
225 * many powers of 2 of 10. Then combine the exponent with the
235 if (exp
> maxExponent
) {
239 for (d
= powersOf10
; exp
!= 0; exp
>>= 1, d
+= 1) {
251 if (endPtr
!= NULL
) {