Annotation of researchv10dc/libI77/notused/ecvt.c, revision 1.1

1.1     ! root        1: /*     @(#)ecvt.c      2.7     */
        !             2: /*     3.0 SID #       1.2     */
        !             3: /*LINTLIBRARY*/
        !             4: /*
        !             5:  *     ecvt converts to decimal
        !             6:  *     the number of digits is specified by ndigit
        !             7:  *     decpt is set to the position of the decimal point
        !             8:  *     sign is set to 0 for positive, 1 for negative
        !             9:  *
        !            10:  */
        !            11: #include <nan.h>
        !            12: #include <values.h>
        !            13: #define        NMAX    ((DSIGNIF * 3 + 19)/10) /* restrict max precision */
        !            14: #define        NDIG    80
        !            15: 
        !            16: extern char *cvt();
        !            17: 
        !            18: char *
        !            19: ecvt(value, ndigit, decpt, sign)
        !            20: double value;
        !            21: int    ndigit, *decpt, *sign;
        !            22: {
        !            23:        return (cvt(value, ndigit, decpt, sign, 0));
        !            24: }
        !            25: 
        !            26: char *
        !            27: fcvt(value, ndigit, decpt, sign)
        !            28: double value;
        !            29: int    ndigit, *decpt, *sign;
        !            30: {
        !            31:        return (cvt(value, ndigit, decpt, sign, 1));
        !            32: }
        !            33: 
        !            34: static char buf[NDIG];
        !            35: 
        !            36: static char *
        !            37: cvt(value, ndigit, decpt, sign, f_flag)
        !            38: double value;
        !            39: int    ndigit, *sign, f_flag;
        !            40: register int   *decpt;
        !            41: {
        !            42:        register char *p = &buf[0], *p_last = &buf[ndigit];
        !            43: 
        !            44:        KILLNaN(value); /* raise exception on Not-a-Number (3b only) */
        !            45:        if (*sign = (value < 0.0))
        !            46:                value = -value;
        !            47:        buf[0] = '\0';
        !            48:        *decpt = 0;
        !            49:        if (value != 0.0) { /* rescale to range [1.0, 10.0) */
        !            50:                /* in binary for speed and to minimize error build-up */
        !            51:                /* even for the IEEE standard with its high exponents,
        !            52:                   it's probably better for speed to just loop on them */
        !            53:                static struct s { double p10; int n; } s[] = {
        !            54:                        1e32,   32,
        !            55:                        1e16,   16,
        !            56:                        1e8,    8,
        !            57:                        1e4,    4,
        !            58:                        1e2,    2,
        !            59:                        1e1,    1,
        !            60:                };
        !            61:                register struct s *sp = s;
        !            62: 
        !            63:                ++*decpt;
        !            64:                if (value >= 2.0 * MAXPOWTWO) /* can't be precisely integral */
        !            65:                        do {
        !            66:                                for ( ; value >= sp->p10; *decpt += sp->n)
        !            67:                                        value /= sp->p10;
        !            68:                        } while (sp++->n > 1);
        !            69:                else if (value >= 10.0) { /* convert integer part separately */
        !            70:                        register double pow10 = 10.0, powtemp;
        !            71: 
        !            72:                        while ((powtemp = 10.0 * pow10) <= value)
        !            73:                                pow10 = powtemp;
        !            74:                        for ( ; ; pow10 /= 10.0) {
        !            75:                                register int digit = value/pow10;
        !            76:                                *p++ = digit + '0';
        !            77:                                value -= digit * pow10;
        !            78:                                ++*decpt;
        !            79:                                if (pow10 <= 10.0)
        !            80:                                        break;
        !            81:                        }
        !            82:                } else if (value < 1.0)
        !            83:                        do {
        !            84:                                for ( ; value * sp->p10 < 10.0; *decpt -= sp->n)
        !            85:                                        value *= sp->p10;
        !            86:                        } while (sp++->n > 1);
        !            87:        }
        !            88:        if (f_flag)
        !            89:                p_last += *decpt;
        !            90:        if (p_last >= buf) {
        !            91:                if (p_last > &buf[NDIG - 2])
        !            92:                        p_last = &buf[NDIG - 2];
        !            93:                for ( ; ; ++p) {
        !            94:                        if (value == 0 || p >= &buf[NMAX])
        !            95:                                *p = '0';
        !            96:                        else {
        !            97:                                register int intx; /* intx in [0, 9] */
        !            98:                                *p = (intx = (int)value) + '0';
        !            99:                                value = 10.0 * (value - (double)intx);
        !           100:                        }
        !           101:                        if (p >= p_last) {
        !           102:                                p = p_last;
        !           103:                                break;
        !           104:                        }
        !           105:                }
        !           106:                if (*p >= '5') /* check rounding in last place + 1 */
        !           107:                        do {
        !           108:                                if (p == buf) { /* rollover from 99999... */
        !           109:                                        buf[0] = '1'; /* later digits are 0 */
        !           110:                                        ++*decpt;
        !           111:                                        if (f_flag)
        !           112:                                                ++p_last;
        !           113:                                        break;
        !           114:                                }
        !           115:                                *p-- = '0';
        !           116:                        } while (++*p > '9'); /* propagate carries left */
        !           117:                *p_last = '\0';
        !           118:        }
        !           119:        return (buf);
        !           120: }

unix.superglobalmegacorp.com

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