home *** CD-ROM | disk | FTP | other *** search
- (*-------------------------------------------------------------------------*)
- (* *)
- (* Amiga Oberon Interface Module: BigQuotients Date: 02-Nov-92 *)
- (* *)
- (* © 1992 by Fridtjof Siebert *)
- (* *)
- (*-------------------------------------------------------------------------*)
-
- MODULE BigQuotients;
-
- IMPORT BT * := BasicTypes, BI * := BigIntegers, Strings;
-
- TYPE
- BigQuotient * = POINTER TO BigQuotientDesc;
- BigQuotientDesc * = RECORD (BT.FIELDDesc)
- p-,
- q-: BI.BigInteger;
- END;
-
-
- VAR
- zero: BI.BigInteger;
-
-
- PROCEDURE Create * (p,q: LONGINT): BigQuotient;
- (*
- * Create new BigQuotient. Set its value to p/q.
- *
- * require
- * -MAX(LONGINT) <= p <= MAX(LONGINT);
- * -MAX(LONGINT) <= q <= MAX(LONGINT);
- * q#0;
- *)
-
- VAR
- bi: BigQuotient;
-
- BEGIN
- NEW(bi);
-
- bi.p := BI.Create(p);
- bi.q := BI.Create(q);
-
- RETURN bi;
- END Create;
-
-
- PROCEDURE (a: BigQuotient) Compare * (b: BT.COMPAREABLE): LONGINT;
- VAR
- ap,bp: BT.COMPAREABLE;
- BEGIN
- WITH b: BigQuotient DO
- ap := a.p.Mul(b.q);
- bp := b.p.Mul(a.q);
- IF a.q.negative = b.q.negative THEN
- RETURN ap.Compare(bp);
- ELSE
- RETURN - ap.Compare(bp);
- END;
- END;
- END Compare;
-
-
- PROCEDURE (m: BigQuotient) Add * (n: BT.GROUP): BT.GROUP;
- VAR
- result: BigQuotient;
- g: BT.GROUP;
- BEGIN
- NEW(result);
- WITH n: BigQuotient DO
- g := m.q.Mul(n.q); result.q := g(BI.BigInteger);
- g := m.p.Mul(n.q); result.p := g(BI.BigInteger);
- g := result.p.Add(n.p.Mul(m.q));
- result.p := g(BI.BigInteger);
- END;
- RETURN result;
- END Add;
-
-
- PROCEDURE (m: BigQuotient) Neg * ( ): BT.GROUP;
- VAR
- result: BigQuotient;
- g: BT.GROUP;
- BEGIN
- NEW(result);
- g := m.p.Neg(); result.p := g(BI.BigInteger);
- g := zero.Add(m.q); result.q := g(BI.BigInteger);
- RETURN result;
- END Neg;
-
-
- PROCEDURE (m: BigQuotient) Norm * (): LONGREAL;
- BEGIN
- RETURN m.p.Norm() / m.q.Norm();
- END Norm;
-
-
- PROCEDURE (m: BigQuotient) Mul * (n: BT.RING): BT.RING;
- VAR
- result: BigQuotient;
- r: BT.RING;
- BEGIN
- NEW(result);
- WITH n: BigQuotient DO
- r := m.p.Mul(n.p); result.p := r(BI.BigInteger);
- r := m.q.Mul(n.q); result.q := r(BI.BigInteger);
- END;
- RETURN result;
- END Mul;
-
-
- PROCEDURE (m: BigQuotient) Inv * (): BT.FIELD;
- VAR
- result: BigQuotient;
- g: BT.GROUP;
- BEGIN
- NEW(result);
- g := m.q.Neg(); result.p := g(BI.BigInteger);
- g := m.p.Neg(); result.q := g(BI.BigInteger);
- RETURN result;
- END Inv;
-
-
- PROCEDURE (m: BigQuotient) InvAllowed * (): BOOLEAN;
- BEGIN
- RETURN m.p.Equal(zero);
- END InvAllowed;
-
-
- PROCEDURE (n: BigQuotient) ConvertToString * (): BT.DynString;
- (*
- * Allocates space for to^ and converts n to an ASCII-String
- *)
- VAR
- ps,qs: BT.DynString;
- p,q: BI.BigInteger;
- g: BT.GROUP;
- neg: BOOLEAN;
- to: BT.DynString;
- BEGIN
- p := n.p;
- q := n.q;
- neg := p.negative # q.negative;
- IF p.negative THEN g := p.Neg(); p := g(BI.BigInteger) END;
- IF q.negative THEN g := q.Neg(); q := g(BI.BigInteger) END;
- ps := p.ConvertToString();
- qs := q.ConvertToString();
- NEW(to,LEN(ps^)+LEN(qs^)+2);
- IF neg THEN to^ := "-"
- ELSE to^ := " " END;
- Strings.Append(to^,ps^);
- Strings.AppendChar(to^,"/");
- Strings.Append(to^,qs^);
- RETURN to;
- END ConvertToString;
-
-
- BEGIN
- zero := BI.Create(0);
- END BigQuotients.
-
-
-
-