Annotation of micropolis/src/tcl/compat/strtod.c, revision 1.1.1.1

1.1       root        1: /* 
                      2:  * strtod.c --
                      3:  *
                      4:  *     Source code for the "strtod" library procedure.
                      5:  *
                      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.
                     14:  */
                     15: 
                     16: #ifndef lint
                     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)";
                     18: #endif /* not lint */
                     19: 
                     20: #include <stdlib.h>
                     21: #include <ctype.h>
                     22: 
                     23: #ifndef TRUE
                     24: #define TRUE 1
                     25: #define FALSE 0
                     26: #endif
                     27: #ifndef NULL
                     28: #define NULL 0
                     29: #endif
                     30: 
                     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.
                     35:                                 */
                     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. */
                     39:     1.0e4,
                     40:     1.0e8,
                     41:     1.0e16,
                     42:     1.0e32,
                     43:     1.0e64,
                     44:     1.0e128,
                     45:     1.0e256
                     46: };
                     47: 
                     48: /*
                     49:  *----------------------------------------------------------------------
                     50:  *
                     51:  * strtod --
                     52:  *
                     53:  *     This procedure converts a floating-point number from an ASCII
                     54:  *     decimal representation to internal double-precision format.
                     55:  *
                     56:  * Results:
                     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.
                     62:  *
                     63:  * Side effects:
                     64:  *     None.
                     65:  *
                     66:  *----------------------------------------------------------------------
                     67:  */
                     68: 
                     69: double
                     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).
                     82:                                 */
                     83:     char **endPtr;             /* If non-NULL, store terminating character's
                     84:                                 * address here. */
                     85: {
                     86:     int sign, expSign = FALSE;
                     87:     double fraction, dblExp, *d;
                     88:     register char *p, c;
                     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
                     98:                                 * dropped digit.
                     99:                                 */
                    100:     int mantSize;              /* Number of digits in mantissa. */
                    101:     int decPt;                 /* Number of mantissa digits BEFORE decimal
                    102:                                 * point.
                    103:                                 */
                    104:     char *pExp;                        /* Temporarily holds location of exponent
                    105:                                 * in string.
                    106:                                 */
                    107: 
                    108:     /*
                    109:      * Strip off leading blanks and check for a sign.
                    110:      */
                    111: 
                    112:     p = string;
                    113:     while (isspace(*p)) {
                    114:        p += 1;
                    115:     }
                    116:     if (*p == '-') {
                    117:        sign = TRUE;
                    118:        p += 1;
                    119:     } else {
                    120:        if (*p == '+') {
                    121:            p += 1;
                    122:        }
                    123:        sign = FALSE;
                    124:     }
                    125: 
                    126:     /*
                    127:      * Count the number of digits in the mantissa (including the decimal
                    128:      * point), and also locate the decimal point.
                    129:      */
                    130: 
                    131:     decPt = -1;
                    132:     for (mantSize = 0; ; mantSize += 1)
                    133:     {
                    134:        c = *p;
                    135:        if (!isdigit(c)) {
                    136:            if ((c != '.') || (decPt >= 0)) {
                    137:                break;
                    138:            }
                    139:            decPt = mantSize;
                    140:        }
                    141:        p += 1;
                    142:     }
                    143: 
                    144:     /*
                    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.
                    149:      */
                    150:     
                    151:     pExp  = p;
                    152:     p -= mantSize;
                    153:     if (decPt < 0) {
                    154:        decPt = mantSize;
                    155:     } else {
                    156:        mantSize -= 1;                  /* One of the digits was the point. */
                    157:     }
                    158:     if (mantSize > 18) {
                    159:        fracExp = decPt - 18;
                    160:        mantSize = 18;
                    161:     } else {
                    162:        fracExp = decPt - mantSize;
                    163:     }
                    164:     if (mantSize == 0) {
                    165:        fraction = 0.0;
                    166:        p = string;
                    167:        goto done;
                    168:     } else {
                    169:        int frac1, frac2;
                    170:        frac1 = 0;
                    171:        for ( ; mantSize > 9; mantSize -= 1)
                    172:        {
                    173:            c = *p;
                    174:            p += 1;
                    175:            if (c == '.') {
                    176:                c = *p;
                    177:                p += 1;
                    178:            }
                    179:            frac1 = 10*frac1 + (c - '0');
                    180:        }
                    181:        frac2 = 0;
                    182:        for (; mantSize > 0; mantSize -= 1)
                    183:        {
                    184:            c = *p;
                    185:            p += 1;
                    186:            if (c == '.') {
                    187:                c = *p;
                    188:                p += 1;
                    189:            }
                    190:            frac2 = 10*frac2 + (c - '0');
                    191:        }
                    192:        fraction = (1.0e9 * frac1) + frac2;
                    193:     }
                    194: 
                    195:     /*
                    196:      * Skim off the exponent.
                    197:      */
                    198: 
                    199:     p = pExp;
                    200:     if ((*p == 'E') || (*p == 'e')) {
                    201:        p += 1;
                    202:        if (*p == '-') {
                    203:            expSign = TRUE;
                    204:            p += 1;
                    205:        } else {
                    206:            if (*p == '+') {
                    207:                p += 1;
                    208:            }
                    209:            expSign = FALSE;
                    210:        }
                    211:        while (isdigit(*p)) {
                    212:            exp = exp * 10 + (*p - '0');
                    213:            p += 1;
                    214:        }
                    215:     }
                    216:     if (expSign) {
                    217:        exp = fracExp - exp;
                    218:     } else {
                    219:        exp = fracExp + exp;
                    220:     }
                    221: 
                    222:     /*
                    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
                    226:      * fraction.
                    227:      */
                    228:     
                    229:     if (exp < 0) {
                    230:        expSign = TRUE;
                    231:        exp = -exp;
                    232:     } else {
                    233:        expSign = FALSE;
                    234:     }
                    235:     if (exp > maxExponent) {
                    236:        exp = maxExponent;
                    237:     }
                    238:     dblExp = 1.0;
                    239:     for (d = powersOf10; exp != 0; exp >>= 1, d += 1) {
                    240:        if (exp & 01) {
                    241:            dblExp *= *d;
                    242:        }
                    243:     }
                    244:     if (expSign) {
                    245:        fraction /= dblExp;
                    246:     } else {
                    247:        fraction *= dblExp;
                    248:     }
                    249: 
                    250: done:
                    251:     if (endPtr != NULL) {
                    252:        *endPtr = p;
                    253:     }
                    254: 
                    255:     if (sign) {
                    256:        return -fraction;
                    257:     }
                    258:     return fraction;
                    259: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.