|
|
1.1 ! root 1: #include <stdio.h> ! 2: #include <assert.h> ! 3: #include "bc.h" ! 4: ! 5: /* ! 6: * Sscale takes the rvalue pointed to by lval and sets ! 7: * the scale register to it if it is in range (ie. non-negative ! 8: * and small enough to fit in an int). ! 9: */ ! 10: ! 11: sscale(lval) ! 12: rvalue *lval; ! 13: { ! 14: register int res; ! 15: ! 16: res = rtoint(lval); ! 17: if (res < 0) ! 18: bcmerr("Invalid scale register value"); ! 19: scale = res; ! 20: } ! 21: ! 22: /* ! 23: * Bcclean frees up the automatic variables and parameters on ! 24: * function exit. `fnc' is the function from which we are returning ! 25: * and `stkp' is a pointer to the top thing to remove. ! 26: */ ! 27: ! 28: bcclean(fnc, stkp) ! 29: func *fnc; ! 30: stkent *stkp; ! 31: { ! 32: register type *tp; ! 33: register int left; ! 34: ! 35: tp = &fnc->types[fnc->nautos + fnc->nparams]; ! 36: for (left = fnc->nautos; --left >= 0; --stkp) ! 37: switch (*--tp) { ! 38: case SCALAR: ! 39: mvfree(&stkp->rvalue.mantissa); ! 40: break; ! 41: case ARRAY: ! 42: arfree(stkp->alvalue); ! 43: mpfree(stkp->alvalue); ! 44: break; ! 45: default: ! 46: assert(FALSE); ! 47: } ! 48: for (left = fnc->nparams; --left >= 0; --stkp) ! 49: switch (*--tp) { ! 50: case SCALAR: ! 51: mvfree(&stkp->rvalue.mantissa); ! 52: break; ! 53: case ARRAY: ! 54: break; ! 55: default: ! 56: assert(FALSE); ! 57: } ! 58: } ! 59: ! 60: /* ! 61: * Bcadd adds the rvalue pointed to by `src' to that pointed to ! 62: * by `dst'. Note that `src' is freed. ! 63: */ ! 64: ! 65: bcadd(src, dst) ! 66: register rvalue *src, *dst; ! 67: { ! 68: if (dst->scale >= src->scale) ! 69: rescale(src, dst->scale); ! 70: else ! 71: rescale(dst, src->scale); ! 72: madd(&dst->mantissa, &src->mantissa, &dst->mantissa); ! 73: mvfree(&src->mantissa); ! 74: } ! 75: ! 76: /* ! 77: * Bcmul multiplies the rvalue pointed to by `dst' by that ! 78: * pointed to by `src'. Note that `src' is freed. ! 79: * The scale factor of the result is set to ! 80: * min( src->scale + dst->scale, max(scale, src->scale, dst->scale)). ! 81: */ ! 82: ! 83: bcmul(src, dst) ! 84: register rvalue *src, *dst; ! 85: { ! 86: register int scl; ! 87: ! 88: mult(&dst->mantissa, &src->mantissa, &dst->mantissa); ! 89: mvfree(&src->mantissa); ! 90: scl = src->scale; ! 91: if (scl < scale) ! 92: scl = scale; ! 93: if (scl < dst->scale) ! 94: scl = dst->scale; ! 95: dst->scale += src->scale; ! 96: if (scl < dst->scale) ! 97: rescale(dst, scl); ! 98: } ! 99: ! 100: /* ! 101: * Bcdiv divides the rvalue pointed to by `dst' by that pointed ! 102: * to by `src'. Note that `src' is freed. The scale of the ! 103: * result is alway equal to the value of the scale register. ! 104: */ ! 105: ! 106: bcdiv(src, dst) ! 107: register rvalue *src, *dst; ! 108: { ! 109: if (zerop(&src->mantissa)) ! 110: bcmerr("Division by zero"); ! 111: rescale(dst, src->scale + scale); ! 112: mdiv(&dst->mantissa, &src->mantissa, &dst->mantissa, &src->mantissa); ! 113: dst->scale = scale; ! 114: mvfree(&src->mantissa); ! 115: } ! 116: ! 117: /* ! 118: * Bcrem sets the rvalue pointed to by `dst' to the remainder one ! 119: * would get when divideing `dst' by `src'. Note that `src' is freed. ! 120: */ ! 121: ! 122: bcrem(src, dst) ! 123: register rvalue *src, *dst; ! 124: { ! 125: if (zerop(&src->mantissa)) ! 126: bcmerr("Modulo zero"); ! 127: rescale(dst, src->scale + scale); ! 128: mdiv(&dst->mantissa, &src->mantissa, &src->mantissa, &dst->mantissa); ! 129: mvfree(&src->mantissa); ! 130: } ! 131: ! 132: /* ! 133: * Bcexp raises the rvalue pointed to by `dst' to the `src' power. ! 134: * Note that first `src' is truncated to an integer. Note that ! 135: * `src' is freed. The scale factor of the result is as if the ! 136: * corresponding multiplications had been done. ! 137: * Negative exponents are computed by inverting dst. ! 138: */ ! 139: ! 140: bcexp(src, dst) ! 141: register rvalue *src, *dst; ! 142: { ! 143: register int limit; ! 144: rvalue temp; ! 145: int rem; ! 146: ! 147: minit(&temp.mantissa); ! 148: if ( ! ispos(&src->mantissa)) { ! 149: mneg(&src->mantissa, &src->mantissa); ! 150: mcopy(mone, &temp.mantissa); ! 151: temp.scale = 0; ! 152: bcdiv(dst, &temp); ! 153: *dst = temp; ! 154: minit(&temp.mantissa); ! 155: } ! 156: shift(&src->mantissa, - src->scale, &temp.mantissa); ! 157: sdiv(&temp.mantissa, 2, &temp.mantissa, &rem); ! 158: if (rem == 0) { ! 159: mvfree(&src->mantissa); ! 160: *src = *dst; ! 161: minit(&dst->mantissa); ! 162: mcopy(mone, &dst->mantissa); ! 163: dst->scale = 0; ! 164: } else { ! 165: mcopy(&dst->mantissa, &src->mantissa); ! 166: src->scale = dst->scale; ! 167: } ! 168: limit = (src->scale > scale ? src->scale : scale); ! 169: while (!zerop(&temp.mantissa)) { ! 170: mult(&src->mantissa, &src->mantissa, &src->mantissa); ! 171: src->scale *= 2; ! 172: if (src->scale > limit) ! 173: rescale(src, limit); ! 174: sdiv(&temp.mantissa, 2, &temp.mantissa, &rem); ! 175: if (rem != 0) { ! 176: mult(&src->mantissa, &dst->mantissa, &dst->mantissa); ! 177: dst->scale += src->scale; ! 178: if (dst->scale > limit) ! 179: rescale(dst, limit); ! 180: } ! 181: } ! 182: mvfree(&temp.mantissa); ! 183: mvfree(&src->mantissa); ! 184: } ! 185: ! 186: /* ! 187: * Bcsqrt relaces the rvalue pointed to by `dst' with its ! 188: * square root. The scale factor of the result is the maximum ! 189: * of the scale register and of the scale of the argument. ! 190: */ ! 191: ! 192: bcsqrt(dst) ! 193: register rvalue *dst; ! 194: { ! 195: register int prec; ! 196: mint temp; ! 197: ! 198: if ( ! ispos(&dst->mantissa)) ! 199: bcmerr("Square root of negative"); ! 200: prec = scale; ! 201: if (prec < dst->scale) ! 202: prec = dst->scale; ! 203: rescale(dst, 2 * prec); ! 204: minit(&temp); ! 205: msqrt(&dst->mantissa, &dst->mantissa, &temp); ! 206: mvfree(&temp); ! 207: dst->scale = prec; ! 208: } ! 209: ! 210: /* ! 211: * Bccmp returns an int which compares to zero as the rvalue `dst' ! 212: * compares to the rvalue `src'. Note that both `src' and `dst' ! 213: * are freed. ! 214: */ ! 215: ! 216: bccmp(src, dst) ! 217: register rvalue *src, *dst; ! 218: { ! 219: register int res; ! 220: ! 221: if (dst->scale >= src->scale) ! 222: rescale(src, dst->scale); ! 223: else ! 224: rescale(dst, src->scale); ! 225: res = mcmp(&dst->mantissa, &src->mantissa); ! 226: mvfree(&src->mantissa); ! 227: mvfree(&dst->mantissa); ! 228: return (res); ! 229: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.