|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1982 Regents of the University of California ! 3: */ ! 4: #ifndef lint ! 5: static char sccsid[] = "@(#)bignum1.c 4.4 6/30/83"; ! 6: #endif not lint ! 7: ! 8: #include <errno.h> ! 9: #include <stdio.h> ! 10: #include "as.h" ! 11: ! 12: Bignum Znumber; ! 13: ! 14: /* ! 15: * Construct an integer. ! 16: */ ! 17: ! 18: Bignum as_atoi(ccp, radix, ovfp) ! 19: reg char *ccp; /* character cp */ ! 20: int radix; ! 21: Ovf *ovfp; ! 22: { ! 23: reg chptr bcp; ! 24: chptr tcp; ! 25: reg int i; ! 26: int val; ! 27: Bignum n_n; ! 28: Bignum t_n; ! 29: int sign; ! 30: Ovf ovf; ! 31: ! 32: ovf = 0; ! 33: sign = 0; ! 34: for (; *ccp; ccp++){ ! 35: switch(*ccp){ ! 36: case '0': ! 37: case '+': continue; ! 38: case '-': sign ^= 1; ! 39: continue; ! 40: } ! 41: break; ! 42: } ! 43: ! 44: n_n = Znumber; ! 45: t_n = Znumber; ! 46: bcp = CH_FIELD(n_n); (void)numclear(bcp); ! 47: tcp = CH_FIELD(t_n); (void)numclear(tcp); ! 48: for (; *ccp; ccp++){ ! 49: switch(*ccp){ ! 50: case '8': case '9': ! 51: if (radix < 10) ! 52: goto done; ! 53: /*FALLTHROUGH*/ ! 54: case '0': case '1': case '2': case '3': case '4': ! 55: case '5': case '6': case '7': ! 56: val = *ccp - '0'; ! 57: break; ! 58: case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': ! 59: if (radix < 16) ! 60: goto done; ! 61: val = *ccp - 'A' + 10; ! 62: break; ! 63: case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': ! 64: if (radix < 16) ! 65: goto done; ! 66: val = *ccp - 'a' + 10; ! 67: break; ! 68: default: ! 69: goto done; ! 70: } ! 71: switch(radix){ ! 72: case 8: ! 73: ovf |= numshift(3, bcp, bcp); ! 74: break; ! 75: case 16: ! 76: ovf |= numshift(4, bcp, bcp); ! 77: break; ! 78: case 10: ! 79: ovf |= numshift(1, tcp, bcp); ! 80: ovf |= numshift(3, bcp, bcp); ! 81: ovf |= numaddv(bcp, tcp, bcp); ! 82: break; ! 83: } ! 84: ovf |= numaddd(bcp, bcp, val); ! 85: } ! 86: done: ; ! 87: ovf |= posovf(bcp); ! 88: if (sign){ ! 89: if (ovf & OVF_MAXINT) { ! 90: ovf &= ~(OVF_MAXINT | OVF_POSOVF); ! 91: } else { ! 92: ovf |= numnegate(bcp, bcp); ! 93: } ! 94: } ! 95: /* ! 96: * find the highest set unit of the number ! 97: */ ! 98: val = sign ? -1 : 0; ! 99: for (i = 0; i < CH_N; i++){ ! 100: if (bcp[i] == val) ! 101: break; ! 102: } ! 103: { ! 104: static u_char tagtab[4][8] = { ! 105: { TYPB, ! 106: TYPW, ! 107: TYPL, TYPL, ! 108: TYPQ, TYPQ, TYPQ, TYPQ }, ! 109: { TYPW, ! 110: TYPL, ! 111: TYPQ, TYPQ }, ! 112: { 0 }, ! 113: { TYPL, ! 114: TYPQ } ! 115: }; ! 116: /* ! 117: * i indexes to the null chunk; make it point to the ! 118: * last non null chunk ! 119: */ ! 120: i -= 1; ! 121: if (i < 0) ! 122: i = 0; ! 123: n_n.num_tag = tagtab[HOC][i]; ! 124: assert(n_n.num_tag != 0, " Botch width computation"); ! 125: } ! 126: *ovfp = ovf; ! 127: return(n_n); ! 128: } ! 129: ! 130: Bignum as_atof (numbuf, radix) ! 131: char *numbuf; ! 132: { ! 133: double atof (); ! 134: Bignum number; ! 135: ! 136: number = Znumber; ! 137: number.num_tag = radix; ! 138: switch (radix) ! 139: { ! 140: case TYPD: ! 141: number.num_num.numFd_float.Fd_value = atof (numbuf); ! 142: break; ! 143: case TYPF: ! 144: number.num_num.numFf_float.Ff_value = atof (numbuf); ! 145: break; ! 146: } ! 147: ! 148: return (number); ! 149: } ! 150: ! 151: Ovf posovf(src) ! 152: reg chptr src; ! 153: { ! 154: reg int i; ! 155: Ovf overflow = 0; ! 156: ! 157: if (src[HOC] & SIGNBIT) ! 158: overflow = OVF_POSOVF; ! 159: if (src[HOC] == SIGNBIT){ ! 160: for (i = HOC - 1; i >= 0; --i){ ! 161: if (src[i] != 0) ! 162: return(overflow); ! 163: } ! 164: overflow |= OVF_MAXINT; ! 165: } ! 166: return(overflow); ! 167: } ! 168: ! 169: /* ! 170: * check if the number is clear ! 171: */ ! 172: int isclear(dst) ! 173: reg chptr dst; ! 174: { ! 175: return(!isunequal(dst, CH_FIELD(Znumber))); ! 176: } ! 177: ! 178: int isunequal(src1, src2) ! 179: reg chptr src1, src2; ! 180: { ! 181: reg int i; ! 182: ! 183: i = CH_N; ! 184: do{ ! 185: if (*src1++ != *src2++) ! 186: return(i); ! 187: }while(--i); ! 188: return(0); ! 189: } ! 190: ! 191: Ovf numclear(dst) ! 192: reg chptr dst; ! 193: { ! 194: reg int i; ! 195: i = CH_N; ! 196: do{ ! 197: *dst++ = 0; ! 198: }while(--i); ! 199: return(0); ! 200: } ! 201: ! 202: Ovf numshift(n, dst, src) ! 203: int n; ! 204: reg chptr dst, src; ! 205: { ! 206: reg int i; ! 207: reg u_int carryi, carryo; ! 208: reg u_int mask; ! 209: reg u_int value; ! 210: ! 211: i = CH_N; ! 212: if (n == 0){ ! 213: do{ ! 214: *dst++ = *src++; ! 215: } while(--i); ! 216: return(0); ! 217: } ! 218: ! 219: carryi = 0; ! 220: mask = ONES(n); ! 221: ! 222: if (n > 0){ ! 223: do{ ! 224: value = *src++; ! 225: carryo = (value >> (CH_BITS - n)) & mask; ! 226: value <<= n; ! 227: value &= ~mask; ! 228: *dst++ = value | carryi; ! 229: carryi = carryo; ! 230: } while (--i); ! 231: return(carryi ? OVF_LSHIFT : 0); ! 232: } else { ! 233: n = -n; ! 234: src += CH_N; ! 235: dst += CH_N; ! 236: do{ ! 237: value = *--src; ! 238: carryo = value & mask; ! 239: value >>= n; ! 240: value &= ONES(CH_BITS - n); ! 241: *--dst = value | carryi; ! 242: carryi = carryo << (CH_BITS - n); ! 243: } while (--i); ! 244: return(carryi ? OVF_LSHIFT : 0); ! 245: } ! 246: } ! 247: ! 248: Ovf numaddd(dst, src1, val) ! 249: chptr dst, src1; ! 250: int val; ! 251: { ! 252: static Bignum work; ! 253: ! 254: work.num_uchar[3] = val; ! 255: return (numaddv(dst, src1, CH_FIELD(work))); ! 256: } ! 257: ! 258: Ovf numaddv(dst, src1, src2) ! 259: reg chptr dst, src1, src2; ! 260: { ! 261: reg int i; ! 262: reg int carry; ! 263: reg u_int A,B,value; ! 264: ! 265: carry = 0; ! 266: i = CH_N; ! 267: do{ ! 268: A = *src1++; ! 269: B = *src2++; ! 270: value = A + B + carry; ! 271: *dst++ = value; ! 272: carry = 0; ! 273: if (value < A || value < B) ! 274: carry = 1; ! 275: } while (--i); ! 276: return(carry ? OVF_ADDV : 0); ! 277: } ! 278: ! 279: Ovf numnegate(dst, src) ! 280: chptr dst, src; ! 281: { ! 282: Ovf ovf; ! 283: ! 284: ovf = num1comp(dst, src) ; ! 285: ovf |= numaddd(dst, dst, 1); ! 286: return(ovf); ! 287: } ! 288: ! 289: Ovf num1comp(dst, src) ! 290: reg chptr dst, src; ! 291: { ! 292: reg int i; ! 293: i = CH_N; ! 294: do{ ! 295: *dst++ = ~ *src++; ! 296: }while (--i); ! 297: return(0); ! 298: } ! 299: ! 300: bignumprint(number) ! 301: Bignum number; /* number presented */ ! 302: { ! 303: switch (num_type) ! 304: { ! 305: case TYPQ: ! 306: printf ("val[msd] = 0x%x, val[lsd] = 0x%x.", ! 307: number.num_num.numIq_int.Iq_ulong[1], ! 308: number.num_num.numIq_int.Iq_ulong[0]); ! 309: break; ! 310: case TYPF: ! 311: printf ("value %20.17f", ! 312: number.num_num.numFf_float.Ff_value); ! 313: break; ! 314: case TYPD: ! 315: printf ("value %20.17f", ! 316: number.num_num.numFd_float.Fd_value); ! 317: break; ! 318: default: ! 319: break; ! 320: } ! 321: } ! 322:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.