|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1982 Regents of the University of California ! 3: */ ! 4: #ifndef lint ! 5: static char sccsid[] = "@(#)natof.c 4.3 2/14/82"; ! 6: #endif not lint ! 7: ! 8: #include <stdio.h> ! 9: #include <ctype.h> ! 10: #include <errno.h> ! 11: ! 12: #include "as.h" ! 13: ! 14: Bignum bigatof(str, radix) ! 15: reg char *str; /* r11 */ ! 16: int radix; /* TYPF ... TYPH */ ! 17: { ! 18: int msign; ! 19: int esign; ! 20: int decpt; ! 21: reg chptr temp; /* r10 */ ! 22: reg u_int quotient; /* r9 */ /* must be here */ ! 23: reg u_int remainder; /* r8 */ /* must be here */ ! 24: reg chptr acc; ! 25: reg int dividend; /* for doing division */ ! 26: reg u_int i; ! 27: short *sptr; /* for doing division */ ! 28: int ch; ! 29: int dexponent; /* decimal exponent */ ! 30: int bexponent; /* binary exponent */ ! 31: Bignum Acc; ! 32: Bignum Temp; ! 33: static Bignum znumber; ! 34: Ovf ovf; ! 35: u_int j; ! 36: extern int errno; ! 37: u_int ediv(); ! 38: ! 39: #ifdef lint ! 40: quotient = 0; ! 41: remainder = 0; ! 42: #endif lint ! 43: msign = 0; ! 44: esign = 0; ! 45: decpt = 0; ! 46: dexponent = 0; ! 47: Acc = znumber; ! 48: Acc.num_tag = radix; ! 49: acc = CH_FIELD(Acc); ! 50: temp = CH_FIELD(Temp); ! 51: ! 52: do{ ! 53: ch = *str++; ! 54: } while(isspace(ch)); ! 55: ! 56: switch(ch){ ! 57: case '-': ! 58: msign = -1; ! 59: /* FALLTHROUGH */ ! 60: case '+': ! 61: ch = *str++; ! 62: break; ! 63: } ! 64: dofract: ! 65: for(; isdigit(ch); ch = *str++){ ! 66: assert(((acc[HOC] & SIGNBIT) == 0), "Negative HOC"); ! 67: if (acc[HOC] < MAXINT_10){ ! 68: ovf = numshift(3, temp, acc); ! 69: ovf |= numshift(1, acc, acc); ! 70: ovf |= numaddv(acc, temp, acc); ! 71: ovf |= numaddd(acc, acc, ch - '0'); ! 72: assert(ovf == 0, "Overflow building mantissa"); ! 73: } else { ! 74: /* ! 75: * Then, the number is too large anyway ! 76: */ ! 77: dexponent++; ! 78: } ! 79: if (decpt) ! 80: dexponent--; ! 81: } ! 82: switch(ch){ ! 83: case '.': ! 84: if (decpt == 0){ ! 85: decpt++; ! 86: ch = *str++; ! 87: goto dofract; ! 88: } ! 89: break; ! 90: /* ! 91: * only 'e' and 'E' are recognized by atof() ! 92: */ ! 93: case 'e': ! 94: case 'E': ! 95: /* ! 96: * we include the remainder for compatability with as formats ! 97: * in as, the radix actual paramater agrees with the character ! 98: * we expect; consequently, no checking is done. ! 99: */ ! 100: case 'd': ! 101: case 'D': ! 102: case 'g': ! 103: case 'G': ! 104: case 'h': ! 105: case 'H': ! 106: j = 0; ! 107: ch = *str++; ! 108: esign = 0; ! 109: switch(ch){ ! 110: case '-': ! 111: esign = 1; ! 112: /* FALLTHROUGH */ ! 113: case '+': ! 114: ch = *str++; ! 115: } ! 116: for(; isdigit(ch); ch = *str++){ ! 117: if (j < MAXINT_10){ ! 118: j *= 10; ! 119: j += ch - '0'; ! 120: } else { ! 121: /* ! 122: * outrageously large exponent ! 123: */ ! 124: /*VOID*/ ! 125: } ! 126: } ! 127: if (esign) ! 128: dexponent -= j; ! 129: else ! 130: dexponent += j; ! 131: /* ! 132: * There should be a range check on dexponent here ! 133: */ ! 134: } ! 135: /* ! 136: * The number has now been reduced to a mantissa ! 137: * and an exponent. ! 138: * The mantissa is an n bit number (to the precision ! 139: * of the extended words) in the acc. ! 140: * The exponent is a signed power of 10 in dexponent. ! 141: * msign is on if the resulting number will eventually ! 142: * be negative. ! 143: * ! 144: * We now must convert the number to standard format floating ! 145: * number, which will be done by accumulating ! 146: * a binary exponent in bexponent, as we gradually ! 147: * drive dexponent towards zero, one count at a time. ! 148: */ ! 149: if (isclear(acc)){ ! 150: return(Acc); ! 151: } ! 152: bexponent = 0; ! 153: ! 154: /* ! 155: * Scale the number down. ! 156: * We must divide acc by 10 as many times as needed. ! 157: */ ! 158: for (; dexponent < 0; dexponent++){ ! 159: /* ! 160: * Align the number so that the most significant ! 161: * bits are aligned in the most significant ! 162: * bits of the accumulator, adjusting the ! 163: * binary exponent as we shift. ! 164: * The goal is to get the high order bit (NOT the ! 165: * sign bit) set. ! 166: */ ! 167: assert(((acc[HOC] & SIGNBIT) == 0), "Negative HOC"); ! 168: ovf = 0; ! 169: ! 170: for (j = 5; j >= 1; --j){ ! 171: i = 1 << (j - 1); /* 16, 8, 4, 2, 1 */ ! 172: quotient = ONES(i); ! 173: quotient <<= (CH_BITS - 1) - i; ! 174: while((acc[HOC] & quotient) == 0){ ! 175: ovf |= numshift((int)i, acc, acc); ! 176: bexponent -= i; ! 177: } ! 178: } ! 179: /* ! 180: * Add 2 to the accumulator to effect rounding, ! 181: * and get set up to divide by 5. ! 182: */ ! 183: ovf = numaddd(acc, acc, 2); ! 184: assert(ovf == 0, "Carry out of left rounding up by 2"); ! 185: /* ! 186: * Divide the high order chunks by 5; ! 187: * The last chunk will be divided by 10, ! 188: * (to see what the remainder is, also to effect rounding) ! 189: * and then multipiled by 2 to effect division by 5. ! 190: */ ! 191: remainder = 0; ! 192: #if DEBUGNATOF ! 193: printf("Dividing: "); ! 194: bignumprint(Acc); ! 195: printf("\n"); ! 196: #endif DEBUGNATOF ! 197: sptr = (short *)acc; ! 198: for (i = (CH_N * 2 - 1); i >= 1; --i){ ! 199: /* ! 200: * Divide (remainder:16).(acc[i]:16) ! 201: * by 5, putting the quotient back ! 202: * into acc[i]:16, and save the remainder ! 203: * for the next iteration. ! 204: */ ! 205: dividend = (remainder << 16) | (sptr[i] & ONES(16)); ! 206: assert(dividend >= 0, "dividend < 0"); ! 207: quotient = dividend / 5; ! 208: remainder = dividend - (quotient * 5); ! 209: sptr[i] = quotient; ! 210: remainder = remainder; ! 211: } ! 212: /* ! 213: * Divide the lowest order chunk by 10, ! 214: * saving the remainder to decide how to round. ! 215: * Then, multiply by 2, making it look as ! 216: * if we divided by 10. ! 217: * This multiply fills in a 0 on the least sig bit. ! 218: */ ! 219: dividend = (remainder << 16) | (sptr[0] & ONES(16)); ! 220: assert(dividend >= 0, "dividend < 0"); ! 221: quotient = dividend / 10; ! 222: remainder = dividend - (quotient * 10); ! 223: sptr[0] = quotient + quotient; ! 224: ! 225: if (remainder >= 5) ! 226: ovf = numaddd(acc, acc, 1); ! 227: /* ! 228: * Now, divide by 2, effecting division by 10, ! 229: * merely by adjusting the binary exponent. ! 230: */ ! 231: bexponent--; ! 232: } ! 233: /* ! 234: * Scale the number up by multiplying by 10 as ! 235: * many times as necessary ! 236: */ ! 237: for (; dexponent > 0; dexponent--){ ! 238: /* ! 239: * Compare high word to (2**31)/5, ! 240: * and scale accordingly ! 241: */ ! 242: while ( ((unsigned)acc[HOC]) > MAXINT_5){ ! 243: (void)numshift(-1, acc, acc); ! 244: bexponent++; ! 245: } ! 246: /* ! 247: * multiply the mantissa by 5, ! 248: * and scale the binary exponent by 2 ! 249: */ ! 250: ovf = numshift(2, temp, acc); ! 251: ovf |= numaddv(acc, acc, temp); ! 252: assert(ovf == 0, "Scaling * 10 of manitissa"); ! 253: bexponent++; ! 254: } ! 255: /* ! 256: * We now have: ! 257: * a CH_N chunk length binary integer, right ! 258: * justified (in native format). ! 259: * a binary exponent. ! 260: * ! 261: * Now, we treat this large integer as an octa word ! 262: * number, and unpack it into standard unpacked ! 263: * format. That unpacking will give us yet ! 264: * another binary exponent, which we adjust with ! 265: * the accumulated binary exponent. ! 266: */ ! 267: Acc.num_tag = TYPO; ! 268: #if DEBUGNATOF ! 269: printf("Octal number: "); ! 270: bignumprint(Acc); ! 271: printf("\n"); ! 272: #endif DEBUGNATOF ! 273: Acc = bignumunpack(Acc, &ovf); ! 274: ! 275: if (ovf) ! 276: errno = ERANGE; ! 277: #if DEBUGNATOF ! 278: printf("Unpacked octal number: "); ! 279: bignumprint(Acc); ! 280: printf("bexponent == %d\n", bexponent); ! 281: #endif DEBUGNATOF ! 282: Acc.num_exponent += bexponent; ! 283: assert(Acc.num_sign == 0, "unpacked integer is < 0"); ! 284: Acc.num_sign = msign; ! 285: /* ! 286: * We now pack the number back into a radix format number. ! 287: * This checks for overflow, underflow, ! 288: * and rounds by 1/2 ulp. ! 289: */ ! 290: ovf = 0; ! 291: Acc = bignumpack(Acc, radix, &ovf); ! 292: if (ovf) ! 293: errno = ERANGE; ! 294: #if DEBUGNATOF ! 295: printf("packed number: "); ! 296: bignumprint(Acc); ! 297: printf("\n"); ! 298: #endif DEBUGNATOF ! 299: return(Acc); ! 300: } ! 301: #if 0 ! 302: /* ! 303: * Unfortunately, one can't use the ediv instruction to do ! 304: * division on numbers with > 64 bits. ! 305: * This is because ediv returns signed quantities; ! 306: * if the quotient is an unsigned number > 2^31, ! 307: * ediv sets integer overflow. ! 308: */ ! 309: unsigned int ediv(high, low, divisor, qp, i) ! 310: register unsigned int high; /* r11 */ ! 311: register unsigned int low; /* r10 */ ! 312: register unsigned int divisor; /* r9 */ ! 313: unsigned int *qp; ! 314: { ! 315: register unsigned int remainder; /* r8 */ ! 316: register unsigned int quotient; /* r7 */ ! 317: ! 318: asm("ediv r9, r10, r7, r8 # Divide. q->r7, r->r8 (discarded)"); ! 319: *qp = quotient; ! 320: return(remainder); ! 321: } ! 322: #endif 0
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.