Annotation of 43BSD/contrib/B/src/bsmall/B1fun.c, revision 1.1.1.1

1.1       root        1: /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
                      2: /* $Header: B1fun.c,v 1.1 84/06/28 00:48:54 timo Exp $ */
                      3: 
                      4: /* B functions */
                      5: #include "b.h"
                      6: #include "b1obj.h"
                      7: #include "b2sem.h"
                      8: #include "B1num.h"
                      9: 
                     10: #define Maxlen(x, y) (Length(x) > Length(y) ? Length(x) : Length(y))
                     11: #define Sumlen(x, y) (Length(x) + Length(y))
                     12: 
                     13: value sum(x, y) register value x, y; {
                     14:        value r, z;
                     15:        Checknum(x); Checknum(y);
                     16:        if (!Exact(x) || !Exact(y)) return mk_approx(Numval(x) + Numval(y));
                     17:        z= mk_exact(Denominator(x), Denominator(y), 0);
                     18:        r= mk_exact(Numerator(x)*Denominator(z)+Numerator(y)*Numerator(z),
                     19:                        Denominator(x)*Denominator(z), Maxlen(x, y));
                     20:        release(z);
                     21:        return r;
                     22: }
                     23: 
                     24: value negated(x) register value x; {
                     25:        Checknum(x);
                     26:        if (!Exact(x)) return mk_approx(-Numval(x));
                     27:        return mk_exact(-Numerator(x), Denominator(x), Length(x));
                     28: }
                     29: 
                     30: value diff(x, y) register value x, y; {
                     31:        value r, my;
                     32:        r= sum(x, my= negated(y));
                     33:        release(my);
                     34:        return r;
                     35: }
                     36: 
                     37: value inverse(x) value x;{
                     38:        Checknum(x);
                     39:        if (Numval(x) == 0) error("in x/y, y is zero");
                     40:        if (!Exact(x)) return mk_approx(1.0/Numval(x));
                     41:        return mk_exact(Denominator(x), Numerator(x), Length(x));
                     42: }
                     43: 
                     44: value prod(x, y) register value x, y; {
                     45:        value a, b, r;
                     46:        Checknum(x); Checknum(y);
                     47:        if (!Exact(x) || !Exact(y)) return mk_approx(Numval(x) * Numval(y));
                     48:        a= mk_exact(Numerator(x), Denominator(y), 0);
                     49:        b= mk_exact(Numerator(y), Denominator(x), 0);
                     50:        r= mk_exact(Numerator(a)*Numerator(b), Denominator(a)*Denominator(b),
                     51:                                                Sumlen(x, y));
                     52:        release(a); release(b);
                     53:        return r;
                     54: }
                     55: 
                     56: value quot(x, y) register value x, y; {
                     57:        value r, iy;
                     58:        r= prod(x, iy= inverse(y));
                     59:        release(iy);
                     60:        return r;
                     61: }
                     62: 
                     63: #define Even(x) ((x) == Two*floor((x)/Two))
                     64: value power(x, y) register value x, y; {
                     65:        Checknum(x); Checknum(y);
                     66:        if (Exact(y)) {
                     67:                integer py= Numerator(y), qy= Denominator(y);
                     68:                if (Integral(y) && Exact(x)) {
                     69:                        integer px, qx, ppx, pqx, Ppx, Pqx;
                     70:                        if (py == Zero) return mk_int(One);
                     71:                        if (py > Zero) {
                     72:                                px= Numerator(x);
                     73:                                qx= Denominator(x);
                     74:                        } else {
                     75:                                py= -py;
                     76:                                px= Denominator(x);
                     77:                                qx= Numerator(x);
                     78:                        }
                     79:                        ppx= pqx= One;
                     80:                        Ppx= px; Pqx= qx;
                     81:                        while (py >= Two) {
                     82:                                if (!Even(py)) {
                     83:                                        ppx*= Ppx; pqx*= Pqx;
                     84:                                }
                     85:                                Ppx*= Ppx; Pqx*= Pqx;
                     86:                                py= floor(py/Two);
                     87:                        }
                     88:                        ppx*= Ppx; pqx*= Pqx;
                     89:                        return mk_exact(ppx, pqx, 0);
                     90:                } /* END Integral(y) && Exact(x) */
                     91:                else {
                     92:                        double vx= Numval(x);
                     93:                        short sx= vx < 0 ? -1 : vx == 0 ? 0 : 1;
                     94:                        if (sx < 0 && Even(qy))
                     95:                            error("in x**(p/q), x is negative and q is even");
                     96:                        if (sx == 0 && py < Zero)
                     97:                            error("0**y with negative y");
                     98:                        if (sx < 0 && Even(py)) sx= 1;
                     99:                        return mk_approx(sx * pow(fabs(vx), py/qy));
                    100:                }
                    101:        } /* END Exact(y) */
                    102:        else {
                    103:                double vx= Numval(x), vy= Approxval(y);
                    104:                if (vy == 0) return mk_approx(1.0);
                    105:                if (vx < 0)
                    106:                        error("in x**y, x is negative and y is not exact");
                    107:                if (vx == 0 && vy < 0)
                    108:                        error("0E0**y with negative y");
                    109:                return mk_approx(pow(vx, vy));
                    110:        }
                    111: }
                    112: 
                    113: value root2(n, x) register value n, x; {
                    114:        value r, in;
                    115:        Checknum(n);
                    116:        if (Numval(n) == 0) error("in x root y, x is zero");
                    117:        r= power(x, in= inverse(n));
                    118:        release(in);
                    119:        return r;
                    120: }
                    121: 
                    122: value absval(x) register value x; {
                    123:        Checknum(x);
                    124:        if (!Exact(x)) return mk_approx(fabs(Numval(x)));
                    125:        return mk_exact((integer) fabs((double) Numerator(x)), Denominator(x), Length(x));
                    126: }
                    127: 
                    128: value signum(x) register value x; {
                    129:        double v= numval(x);
                    130:        return mk_int(v < 0 ? -One : v == 0 ? Zero : One);
                    131: }
                    132: 
                    133: value floorf(x) register value x; {
                    134:        return mk_int(floor(numval(x)));
                    135: }
                    136: 
                    137: value ceilf(x) register value x; {
                    138:        return mk_int(ceil(numval(x)));
                    139: }
                    140: 
                    141: value round1(x) register value x; {
                    142:        return mk_int(floor(numval(x) + .5));
                    143: }
                    144: 
                    145: value round2(n, x) register value n, x; {
                    146:        value ten, tenp, xtenp, r0, r;
                    147:        Checknum(n);
                    148:        if (!Integral(n)) error("in n round x, n is not an integer");
                    149:        ten= mk_integer(10);
                    150:        tenp= power(ten, n);
                    151:        xtenp= prod(x, tenp);
                    152:        r0= round1(xtenp);
                    153:        r= mk_exact(Numerator(r0), Numerator(tenp), propintlet((int) Numerator(n)));
                    154:        release(ten); release(tenp); release(xtenp); release(r0);
                    155:        return r;
                    156: }
                    157: 
                    158: value mod(a, n) register value a, n; {
                    159:        value f, p, d;
                    160:        Checknum(a); Checknum(n);
                    161:        f= mk_int(floor(Numval(a) / Numval(n)));
                    162:        p= prod(n, f);
                    163:        d= diff(a, p);
                    164:        release(f); release(p);
                    165:        return d;
                    166: }
                    167: 
                    168: double lastran;
                    169: 
                    170: setran (seed) double seed;
                    171: {double x;
                    172:  x= seed >= 0 ? seed : -seed;
                    173:  while (x >= 1) x/= 10;
                    174:  lastran= floor(67108864.0 * x);
                    175: }
                    176: 
                    177: set_random(v) value v; {
                    178:        setran((double) hash(v));
                    179: }
                    180: 
                    181: value random() /* 0 <= r < 1 */
                    182: {double p;
                    183:  p= 26353589.0 * lastran + 1;
                    184:  lastran= p - 67108864.0 * floor (p / 67108864.0);
                    185:  return mk_approx(lastran / 67108864.0);
                    186: }
                    187: 
                    188: value root1(v) value v; {
                    189:        value two= mk_integer(2);
                    190:        v= root2(two, v);
                    191:        release(two);
                    192:        return(v);
                    193: }
                    194: 
                    195: value pi() { return mk_approx(3.141592653589793238462); }
                    196: value e() { return mk_approx(exp(1.0)); }
                    197: 
                    198: value sin1(v) value v; { return mk_approx(sin(numval(v))); }
                    199: value cos1(v) value v; { return mk_approx(cos(numval(v))); }
                    200: value tan1(v) value v; { return mk_approx(tan(numval(v))); }
                    201: value atn1(v) value v; { return mk_approx(atan(numval(v))); }
                    202: value exp1(v) value v; { return mk_approx(exp(numval(v))); }
                    203: value log1(v) value v; { return mk_approx(log(numval(v))); }
                    204: 
                    205: value log2(u, v) value u, v;{
                    206:        return mk_approx(log(numval(v)) / log(numval(u)));
                    207: }
                    208: 
                    209: value atn2(u, v) value u, v; {
                    210:        return mk_approx(atan2(numval(v), numval(u)));
                    211: }

unix.superglobalmegacorp.com

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