Annotation of coherent/b/bin/c/n0/double.c, revision 1.1.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.