Annotation of coherent/b/bin/c/n0/double.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * This file contains a (mostly) machine independent
        !             3:  * IEEE or DECVAX format floating point reader.
        !             4:  */
        !             5: 
        !             6: #ifdef   vax
        !             7: #include "INC$LIB:cc0.h"
        !             8: #else
        !             9: #include "cc0.h"
        !            10: #endif
        !            11: 
        !            12: #if !NATIVEFP
        !            13: #if IEEE|DECVAX
        !            14: 
        !            15: #define        NEGNUMB 01                      /* # is negative */
        !            16: #define        DOTSEEN 02                      /* A decimal point has appeared */
        !            17: #define        NEGDEXP 04                      /* Decimal exp. is negative */
        !            18: 
        !            19: /*
        !            20:  * The following values are returned on exponent overflow.
        !            21:  * The bits are the same in both formats.
        !            22:  * This does not use the special IEEE representation for Infinity.
        !            23:  */
        !            24: static BIG poshuge = { 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
        !            25: static BIG neghuge = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
        !            26: 
        !            27: /*
        !            28:  * Transform a number from ASCII to either
        !            29:  * IEEE format double precision or
        !            30:  * DEC VAX-11 format double precision.
        !            31:  * Stash the result in the supplied character array.
        !            32:  * The 0'th element gets the exponent end of the number.
        !            33:  * The internal representation used here is a BIG,
        !            34:  * an array of bytes containing the binary mantissa.
        !            35:  */
        !            36: dvalread(dvalp, sp)
        !            37: char           *dvalp;
        !            38: register char  *sp;
        !            39: {
        !            40:        register int    c;
        !            41:        int             binexp, decexp;
        !            42:        int             flags, i, n;
        !            43:        BIG             num, tmp;
        !            44: 
        !            45:        intclr(num);
        !            46:        flags  = 0;
        !            47:        decexp = 0;
        !            48:        binexp = 64;
        !            49:        if (*sp == '+')
        !            50:                ++sp;
        !            51:        else if (*sp == '-') {
        !            52:                flags |= NEGNUMB;
        !            53:                ++sp;
        !            54:        }
        !            55:        while ((c = *sp++)=='.' || (c>='0' && c<='9')) {
        !            56:                if (c == '.') {
        !            57:                        if ((flags&DOTSEEN) != 0)
        !            58:                                break;
        !            59:                        flags |= DOTSEEN;
        !            60:                } else {
        !            61:                        if (t5ne(num))
        !            62:                                ++decexp;
        !            63:                        else {
        !            64:                                intshl(num);
        !            65:                                intcpy(tmp, num);
        !            66:                                intshl(num);
        !            67:                                intshl(num);
        !            68:                                intadd(num, tmp);
        !            69:                                intclr(tmp);
        !            70:                                tmp[NBIG-1] = c-'0';
        !            71:                                intadd(num, tmp);
        !            72:                        }
        !            73:                        if ((flags&DOTSEEN) != 0)
        !            74:                                --decexp;
        !            75:                }
        !            76:        }
        !            77:        /*
        !            78:         * If the delimiter is an 'e' or an 'E',
        !            79:         * read in the exponent and adjust the decimal bias.
        !            80:         */
        !            81:        if (c=='e' || c=='E') {
        !            82:                if (*sp == '+')
        !            83:                        ++sp;
        !            84:                else if (*sp == '-') {
        !            85:                        flags |= NEGDEXP;
        !            86:                        ++sp;
        !            87:                }
        !            88:                n = 0;
        !            89:                while ((c = *sp++)>='0' && c<='9')
        !            90:                        n = 10*n + c - '0';
        !            91:                if ((flags&NEGDEXP) != 0)
        !            92:                        n = -n;
        !            93:                decexp += n;
        !            94:        }
        !            95:        /*
        !            96:         * Check for 0.0.
        !            97:         * Double 0.0 is a BIG containing all 0 bytes in both formats.
        !            98:         */
        !            99:        for (i=0; i<NBIG && num[i]==0; ++i)
        !           100:                ;
        !           101:        if (i == NBIG) {
        !           102:                intclr(dvalp);
        !           103:                return;
        !           104:        }
        !           105:        /*
        !           106:         * Multiply.
        !           107:         * Try to do a *5.
        !           108:         * If ok, add 1 to the binary exponent (2*5=10).
        !           109:         * Otherwise, multiply by 5/4, add 3 to the binary exponent (5/4*8=10).
        !           110:         */
        !           111:        if (decexp > 0) {
        !           112:                do {
        !           113:                        intcpy(tmp, num);
        !           114:                        if (intshl(tmp)==0 && intshl(tmp)==0
        !           115:                        &&  intadd(tmp, num)==0) {
        !           116:                                intcpy(num, tmp);
        !           117:                                ++binexp;
        !           118:                        } else {
        !           119:                                intcpy(tmp, num);
        !           120:                                intshr(tmp);
        !           121:                                intshr(tmp);
        !           122:                                if (intadd(num, tmp) != 0) {
        !           123:                                        ++binexp;
        !           124:                                        intshr(num);
        !           125:                                        num[0] |= MSBBIG;
        !           126:                                }
        !           127:                                binexp += 3;
        !           128:                        }
        !           129:                } while (--decexp);
        !           130:        /*
        !           131:         * Divide.
        !           132:         * At each iteration, subtract 3 from the exponent
        !           133:         * and multiply by 4/5 (4/5*1/8=1/10).
        !           134:         * 4/5 = 0.1100110011001100....
        !           135:         */
        !           136:        } else if (decexp < 0) {
        !           137:                do {
        !           138:                        while ((num[0]&MSBBIG) == 0) {
        !           139:                                intshl(num);
        !           140:                                --binexp;
        !           141:                        }
        !           142:                        intshr(num);
        !           143:                        intcpy(tmp, num);
        !           144:                        for (i=0; i<32; ++i) {
        !           145:                                if ((i&01) != 0) {
        !           146:                                        intshr(tmp);
        !           147:                                        intshr(tmp);
        !           148:                                }
        !           149:                                intshr(tmp);
        !           150:                                intadd(num, tmp);
        !           151:                        }
        !           152:                        binexp -= 3;
        !           153:                } while (++decexp);
        !           154:        }
        !           155:        /*
        !           156:         * Normalize and eat up the hidden bit.
        !           157:         */
        !           158:        do {
        !           159:                --binexp;
        !           160:        } while (intshl(num) == 0);
        !           161:        intclr(tmp);
        !           162:        tmp[IROUND] = BROUND;
        !           163:        if (intadd(num, tmp) != 0) {
        !           164:                ++binexp;
        !           165:                intshr(num);
        !           166:        }
        !           167:        /*
        !           168:         * Bias the exponent and check its range.
        !           169:         * This does not bother to use the special IEEE representation
        !           170:         * (exponent 0, mantissa nonzero) for a bit more range.
        !           171:         * Overflow returns the biggest value in the normal representation;
        !           172:         * IEEE overflow could return Infinity instead but currently does not.
        !           173:         */
        !           174:        binexp += EXPBIAS;
        !           175:        if (binexp <= 0) {
        !           176:                cwarn("exponent underflow in floating point constant");
        !           177:                intclr(dvalp);
        !           178:                return;
        !           179:        }
        !           180:        if (binexp > EXPMAX) {
        !           181:                cwarn("exponent overflow in floating point constant");
        !           182:                intcpy(dvalp, (flags&NEGNUMB)!=0 ? neghuge : poshuge);
        !           183:                return;
        !           184:        }
        !           185:        /*
        !           186:         * Pack up and return home.
        !           187:         */
        !           188: #if IEEE
        !           189:        for (i=0; i<12; ++i)
        !           190:                intshr(num);
        !           191:        num[0]  = (binexp>>4) & 0177;
        !           192:        num[1] |= (binexp<<4) & 0360;
        !           193: #else
        !           194:        for (i=0; i<9;  ++i)
        !           195:                intshr(num);
        !           196:        num[0]  = (binexp>>1) & 0177;
        !           197:        num[1] |= (binexp<<7) & 0200;
        !           198: #endif
        !           199:        if (flags&NEGNUMB != 0)
        !           200:                num[0] |= MSBBIG;
        !           201:        intcpy(dvalp, num);
        !           202: }
        !           203: 
        !           204: /*
        !           205:  * Shift a BIG right by 1 bit.
        !           206:  * Shift a 0 into the leftmost position.
        !           207:  * Return the bit that gets shot off the end.
        !           208:  */
        !           209: intshr(num)
        !           210: BIG    num;
        !           211: {
        !           212:        register int    i, ocarry, icarry;
        !           213: 
        !           214:        ocarry = 0;
        !           215:        for (i=0; i<NBIG; ++i) {
        !           216:                icarry = ocarry;
        !           217:                ocarry = num[i]&01;
        !           218:                num[i] >>= 1;
        !           219:                if (icarry != 0)
        !           220:                        num[i] |= MSBBIG;
        !           221:        }
        !           222:        return (ocarry);
        !           223: }
        !           224: 
        !           225: /*
        !           226:  * Shift a BIG left by 1 bit.
        !           227:  * Shift a 0 into the rightmost position.
        !           228:  * Return the bit that gets shot off the end.
        !           229:  */
        !           230: static
        !           231: intshl(num)
        !           232: BIG    num;
        !           233: {
        !           234:        register int    i, ocarry, icarry;
        !           235: 
        !           236:        ocarry = 0;
        !           237:        for (i=NBIG-1; i>=0; --i) {
        !           238:                icarry = ocarry;
        !           239:                ocarry = num[i]&MSBBIG;
        !           240:                num[i] <<= 1;
        !           241:                if (icarry != 0)
        !           242:                        num[i] |= 1;
        !           243:        }
        !           244:        return (ocarry);
        !           245: }
        !           246: 
        !           247: /*
        !           248:  * Add two BIGs.
        !           249:  * Return the carry bit.
        !           250:  */
        !           251: intadd(num, tmp)
        !           252: BIG    num;
        !           253: BIG    tmp;
        !           254: {
        !           255:        register int    i, sum;
        !           256: 
        !           257:        sum = 0;
        !           258:        for (i=NBIG-1; i>=0; --i) {
        !           259:                sum += num[i] + tmp[i];
        !           260:                num[i] = sum;
        !           261:                sum = cbit(sum);
        !           262:        }
        !           263:        return (sum);
        !           264: }
        !           265: 
        !           266: /*
        !           267:  * Copy a BIG.
        !           268:  */
        !           269: intcpy(tint, fint)
        !           270: BIG    tint;
        !           271: BIG    fint;
        !           272: {
        !           273:        register int    i;
        !           274: 
        !           275:        for (i=0; i<NBIG; ++i)
        !           276:                tint[i] = fint[i];
        !           277: }
        !           278: 
        !           279: /*
        !           280:  * Set a BIG to 0.
        !           281:  */
        !           282: intclr(tint)
        !           283: BIG    tint;
        !           284: {
        !           285:        register int    i;
        !           286: 
        !           287:        for (i=0; i<NBIG; ++i)
        !           288:                tint[i] = 0;
        !           289: }
        !           290: 
        !           291: #endif
        !           292: #endif

unix.superglobalmegacorp.com

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