Annotation of coherent/b/lib/libc/gen/atof.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * /usr/src/libc/gen/atof.c
        !             3:  * C general utilities library.
        !             4:  * atof()
        !             5:  * ANSI 4.10.1.1.
        !             6:  * Convert ASCII to double (the old fashioned way).
        !             7:  * Builds significand in an unsigned long, for efficiency.
        !             8:  * Does not use any knowledge about floating point representation.
        !             9:  */
        !            10: 
        !            11: #if    __STDC__
        !            12: #include <stdlib.h>
        !            13: #include <limits.h>
        !            14: #include <locale.h>
        !            15: #else
        !            16: #define        _decimal_point  '.'
        !            17: extern double  _pow10();
        !            18: #endif
        !            19: #include <ctype.h>
        !            20: 
        !            21: /* Flag bits. */
        !            22: #define        NEG     1                       /* negative significand */
        !            23: #define        DOT     2                       /* decimal point seen   */
        !            24: #define        NEGEXP  4                       /* negative exponent    */
        !            25: #define        BIG     8                       /* significand too big for ulong */
        !            26: 
        !            27: double
        !            28: atof(nptr) register char *nptr;
        !            29: {
        !            30:        register int            c, flag, eexp;
        !            31:        register unsigned long  val;
        !            32:        int                     exp, vdigits;
        !            33:        double                  d;
        !            34: 
        !            35:        val = flag = exp = vdigits = 0;
        !            36: 
        !            37:        /* Leading white space. */
        !            38:        while (isspace(c = *nptr++))
        !            39:                ;
        !            40: 
        !            41:        /* Optional sign. */
        !            42:        switch (c) {
        !            43:        case '-':
        !            44:                flag |= NEG;
        !            45:        case '+':
        !            46:                c = *nptr++;
        !            47:        }
        !            48: 
        !            49:        /* Number: sequence of decimal digits with optional '.'. */
        !            50:        for (; ; c = *nptr++) {
        !            51:                if (isdigit(c)) {
        !            52:                        c -= '0';
        !            53:                        if (c == 0 && (flag & DOT)) {
        !            54:                                /* Check for trailing zeros to avoid imprecision. */
        !            55:                                char *look, d;
        !            56: 
        !            57:                                for (look = nptr; (d = *look++) == '0'; )
        !            58:                                        ;               /* skip a trailing zero */
        !            59:                                if (!isdigit(d)) {      /* ignore zeroes */
        !            60:                                        nptr = look;
        !            61:                                        c = d;
        !            62:                                        break;
        !            63:                                }                       /* else don't ignore */
        !            64:                        }
        !            65: #if    __STDC__
        !            66:                        if (val > (ULONG_MAX-9) / 10) {
        !            67: #else
        !            68:                        /* The pre-ANSI compiler gets the test above wrong. */
        !            69:                        if (val > 429496728L) {
        !            70: #endif
        !            71:                                /* Significand too big for val, use d. */
        !            72:                                if (flag & BIG)
        !            73:                                        d = d * _pow10(vdigits) + val;  
        !            74:                                else {
        !            75:                                        d = val;
        !            76:                                        flag |= BIG;
        !            77:                                }
        !            78:                                vdigits = 1;
        !            79:                                val = c;
        !            80:                        } else {
        !            81:                                ++vdigits;      /* decimal digits in val */
        !            82:                                /* val = val * 10 + c; */
        !            83:                                val <<= 1;
        !            84:                                val = val + (val << 2) + c;
        !            85:                        }
        !            86:                        if (flag & DOT)
        !            87:                                --exp;
        !            88:                } else if (c == _decimal_point && (flag & DOT) == 0)
        !            89:                        flag |= DOT;
        !            90:                else
        !            91:                        break;
        !            92:        }
        !            93:        if (flag & BIG)
        !            94:                d = d * _pow10(vdigits) + val;
        !            95:        else
        !            96:                d = val;
        !            97: 
        !            98:        /* Optional exponent: 'E' or 'e', optional sign, decimal digits. */
        !            99:        if (c == 'e'  ||  c == 'E') {
        !           100: 
        !           101:                /* Optional sign. */
        !           102:                switch (c = *nptr++) {
        !           103:                case '-':
        !           104:                        flag |= NEGEXP;
        !           105:                case '+':
        !           106:                        c = *nptr++;
        !           107:                }
        !           108: 
        !           109:                /* Decimal digits. */
        !           110:                for (eexp = 0; isdigit(c); c = *nptr++)
        !           111:                        eexp = eexp * 10 + c - '0';
        !           112: 
        !           113:                /* Adjust explicit exponent for digits read after '.'. */
        !           114:                if (flag & NEGEXP)
        !           115:                        exp -= eexp;
        !           116:                else
        !           117:                        exp += eexp;
        !           118:        }
        !           119: 
        !           120:        /* Reconcile the significand with the exponent and sign. */
        !           121:        if (exp != 0)
        !           122:                d *= _pow10(exp);
        !           123:        return ((flag & NEG) ? -d : d);
        !           124: }
        !           125: 
        !           126: /* end of libc/gen/atof.c */

unix.superglobalmegacorp.com

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