Annotation of coherent/d/bin/bc/bcmch.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.