Annotation of micropolis/src/tcl/compat/strtod.c, revision 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.