Annotation of coherent/b/lib/libc/XSTDIO/ndpobj/atof.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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