Annotation of 43BSDTahoe/new/B/src/bint/b1nuR.c, revision 1.1

1.1     ! root        1: /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
        !             2: 
        !             3: /*
        !             4:   $Header: b1nuR.c,v 1.4 85/08/22 16:51:49 timo Exp $
        !             5: */
        !             6: 
        !             7: /* Rational arithmetic */
        !             8: 
        !             9: #include "b.h"
        !            10: #include "b0con.h"
        !            11: #include "b1obj.h"
        !            12: #include "b1num.h"
        !            13: #include "b3err.h"
        !            14: 
        !            15: /* Length calculations used for fraction sizes: */
        !            16: #define Maxlen(u, v) \
        !            17:        (Roundsize(u) > Roundsize(v) ? Roundsize(u) : Roundsize(v))
        !            18: #define Sumlen(u, v) (Roundsize(u)+Roundsize(v))
        !            19: #define Difflen(u, v) (Roundsize(u)-Roundsize(v))
        !            20: 
        !            21: /* To shut off lint and other warnings: */
        !            22: #undef Copy
        !            23: #define Copy(x) ((integer)copy((value)(x)))
        !            24: 
        !            25: /* Globally used constants */
        !            26: 
        !            27: rational rat_zero;
        !            28: rational rat_half;
        !            29: 
        !            30: /* Make a normalized rational from two integers */
        !            31: 
        !            32: Visible rational mk_rat(x, y, len) integer x, y; int len; {
        !            33:        rational a;
        !            34:        integer u,v;
        !            35: 
        !            36:        if (y == int_0) {
        !            37:                if (interrupted)
        !            38:                        return rat_zero;
        !            39:                syserr(MESS(1200, "mk_rat(x, y) with y=0"));
        !            40:        }
        !            41: 
        !            42:        if (x == int_0 && len <= 0) return (rational) Copy(rat_zero);
        !            43: 
        !            44:        if (Msd(y) < 0) {       /* interchange signs */
        !            45:                u = int_neg(x);
        !            46:                v = int_neg(y);
        !            47:        } else {
        !            48:                u = Copy(x);
        !            49:                v = Copy(y);
        !            50:        }
        !            51: 
        !            52:        a = (rational) grab_rat();
        !            53:        if (len > 0 && len+2 <= Maxintlet) Length(a) = -2 - len;
        !            54: 
        !            55:        if (u == int_0 || v == int_1) {
        !            56:                /* No simplification possible */
        !            57:                Numerator(a) = Copy(u);
        !            58:                Denominator(a) = int_1;
        !            59:        } else {
        !            60:                integer g, abs_u;
        !            61: 
        !            62:                if (Msd(u) < 0) abs_u = int_neg(u);
        !            63:                else abs_u = Copy(u);
        !            64:                g = int_gcd(abs_u, v);
        !            65:                release((value) abs_u);
        !            66: 
        !            67:                if (g != int_1) {
        !            68:                        Numerator(a) = int_quot(u, g);
        !            69:                        Denominator(a) = int_quot(v, g);
        !            70:                } else {
        !            71:                        Numerator(a) = Copy(u);
        !            72:                        Denominator(a) = Copy(v);
        !            73:                }
        !            74:                release((value) g);
        !            75:        }
        !            76: 
        !            77:        release((value) u); release((value) v);
        !            78: 
        !            79:        return a;
        !            80: }
        !            81: 
        !            82: 
        !            83: /* Arithmetic on rational numbers */
        !            84: 
        !            85: /* Shorthands: */
        !            86: #define N(u) Numerator(u)
        !            87: #define D(u) Denominator(u)
        !            88: 
        !            89: Visible rational rat_sum(u, v) register rational u, v; {
        !            90:        integer t1, t2, t3, t4;
        !            91:        rational a;
        !            92: 
        !            93:        t2= int_prod(N(u), D(v));
        !            94:        t3= int_prod(N(v), D(u));
        !            95:        t1= int_sum(t2, t3);
        !            96:        t4= int_prod(D(u), D(v));
        !            97:        a= mk_rat(t1, t4, Maxlen(u, v));
        !            98:        release((value) t1); release((value) t2);
        !            99:        release((value) t3); release((value) t4);
        !           100: 
        !           101:        return a;
        !           102: }
        !           103: 
        !           104: 
        !           105: Visible rational rat_diff(u, v) register rational u, v; {
        !           106:        integer t1, t2, t3, t4;
        !           107:        rational a;
        !           108: 
        !           109:        t2= int_prod(N(u), D(v));
        !           110:        t3= int_prod(N(v), D(u));
        !           111:        t1= int_diff(t2, t3);
        !           112:        t4= int_prod(D(u), D(v));
        !           113:        a= mk_rat(t1, t4, Maxlen(u, v));
        !           114:        release((value) t1); release((value) t2);
        !           115:        release((value) t3); release((value) t4);
        !           116: 
        !           117:        return a;
        !           118: }
        !           119: 
        !           120: 
        !           121: Visible rational rat_prod(u, v) register rational u, v; {
        !           122:        integer t1, t2;
        !           123:        rational a;
        !           124: 
        !           125:        t1= int_prod(N(u), N(v));
        !           126:        t2= int_prod(D(u), D(v));
        !           127:        a= mk_rat(t1, t2, Sumlen(u, v));
        !           128:        release((value) t1); release((value) t2);
        !           129: 
        !           130:        return a;
        !           131: }
        !           132: 
        !           133: 
        !           134: Visible rational rat_quot(u, v) register rational u, v; {
        !           135:        integer t1, t2;
        !           136:        rational a;
        !           137: 
        !           138:        if (Numerator(v) == int_0) {
        !           139:                error(MESS(1201, "in u/v, v is zero"));
        !           140:                return (rational) Copy(rat_zero);
        !           141:        }
        !           142: 
        !           143:        t1= int_prod(N(u), D(v));
        !           144:        t2= int_prod(D(u), N(v));
        !           145:        a= mk_rat(t1, t2, Difflen(u, v));
        !           146:        release((value) t1); release((value) t2);
        !           147: 
        !           148:        return a;
        !           149: }
        !           150: 
        !           151: 
        !           152: Visible rational rat_neg(u) register rational u; {
        !           153:        register rational a;
        !           154: 
        !           155:        /* Avoid a real subtraction from zero */
        !           156: 
        !           157:        if (Numerator(u) == int_0) return (rational) Copy(u);
        !           158: 
        !           159:        a = (rational) grab_rat();
        !           160:        N(a) = int_neg(N(u));
        !           161:        D(a) = Copy(D(u));
        !           162:        Length(a) = Length(u);
        !           163: 
        !           164:        return a;
        !           165: }
        !           166: 
        !           167: 
        !           168: /* Rational number to the integral power */
        !           169: 
        !           170: Visible rational rat_power(a, n) rational a; integer n; {
        !           171:        integer u, v, tu, tv, temp;
        !           172: 
        !           173:        if (n == int_0) return mk_rat(int_1, int_1, 0);
        !           174: 
        !           175:        if (Msd(n) < 0) {
        !           176:                if (Numerator(a) == int_0) {
        !           177:                        error(MESS(1202, "in 0**n, n is negative"));
        !           178:                        return (rational) Copy(a);
        !           179:                }
        !           180:                if (Msd(Numerator(a)) < 0) {
        !           181:                        u= int_neg(Denominator(a));
        !           182:                        v = int_neg(Numerator(a));
        !           183:                }
        !           184:                else {
        !           185:                        u = Copy(Denominator(a));
        !           186:                        v = Copy(Numerator(a));
        !           187:                }
        !           188:                n = int_neg(n);
        !           189:        } else {
        !           190:                if (Numerator(a) == int_0) return (rational) Copy(a);
        !           191:                        /* To avoid necessary simplification later on */
        !           192:                u = Copy(Numerator(a));
        !           193:                v = Copy(Denominator(a));
        !           194:                n = Copy(n);
        !           195:        }
        !           196: 
        !           197:        tu = int_1;
        !           198:        tv = int_1;
        !           199: 
        !           200:        while (n != int_0 && !interrupted) {
        !           201:                if (Odd(Lsd(n))) {
        !           202:                        if (u != int_1) {
        !           203:                                temp = tu;
        !           204:                                tu = int_prod(u, tu);
        !           205:                                release((value) temp);
        !           206:                        }
        !           207:                        if (v != int_1) {
        !           208:                                temp = tv;
        !           209:                                tv = int_prod(v, tv);
        !           210:                                release((value) temp);
        !           211:                        }
        !           212:                        if (n == int_1)
        !           213:                                break; /* Avoid useless last squaring */
        !           214:                }
        !           215: 
        !           216:                /* Square u, v */
        !           217: 
        !           218:                if (u != int_1) {
        !           219:                        temp = u;
        !           220:                        u = int_prod(u, u);
        !           221:                        release((value) temp);
        !           222:                }
        !           223:                if (v != int_1) {
        !           224:                        temp = v;
        !           225:                        v = int_prod(v, v);
        !           226:                        release((value) temp);
        !           227:                }
        !           228: 
        !           229:                n = int_half(n);
        !           230:        } /* while (n!=0) */
        !           231: 
        !           232:        release((value) n);
        !           233:        release((value) u);
        !           234:        release((value) v);
        !           235:        a = (rational) grab_rat();
        !           236:        Numerator(a) = tu;
        !           237:        Denominator(a) = tv;
        !           238: 
        !           239:        return a;
        !           240: }
        !           241: 
        !           242: 
        !           243: /* Compare two rational numbers */
        !           244: 
        !           245: Visible relation rat_comp(u, v) register rational u, v; {
        !           246:        int sd, su, sv;
        !           247:        integer nu, nv;
        !           248: 
        !           249:        /* 1. Compare pointers */
        !           250:        if (u == v || N(u) == N(v) && D(u) == D(v)) return 0;
        !           251: 
        !           252:        /* 2. Either zero? */
        !           253:        if (N(u) == int_0) return int_comp(int_0, N(v));
        !           254:        if (N(v) == int_0) return int_comp(N(u), int_0);
        !           255: 
        !           256:        /* 3. Compare signs */
        !           257:        su = Msd(N(u));
        !           258:        sv = Msd(N(v));
        !           259:        su = (su>0) - (su<0);
        !           260:        sv = (sv>0) - (sv<0);
        !           261:        if (su != sv) return su > sv ? 1 : -1;
        !           262: 
        !           263:        /* 4. Compute numerator of difference and return sign */
        !           264:        nu= int_prod(N(u), D(v));
        !           265:        nv= int_prod(N(v), D(u));
        !           266:        sd= int_comp(nu, nv);
        !           267:        release((value) nu); release((value) nv);
        !           268:        return sd;
        !           269: }
        !           270: 
        !           271: Visible Procedure rat_init() {
        !           272:        rat_zero = (rational) grab_rat();
        !           273:        Numerator(rat_zero) = int_0;
        !           274:        Denominator(rat_zero) = int_1;
        !           275: 
        !           276:        rat_half = (rational) grab_rat();
        !           277:        Numerator(rat_half) = int_1;
        !           278:        Denominator(rat_half) = int_2;
        !           279: }
        !           280: 
        !           281: Visible Procedure endrat() {
        !           282:        release((value) rat_zero);
        !           283:        release((value) rat_half);
        !           284: }

unix.superglobalmegacorp.com

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