|
|
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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.