Annotation of coherent/b/lib/libc/gen/atof.c, revision 1.1.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.