DIRECTORY BigCardinals USING [BigAdd, BigCARD, BigCompare, BigDivMod, BigFromBinaryRope, BigFromDecimalRope, BigFromSmall, BigMultiply, BigSubtract, BigToDecimalRope, BigZero, Zero], BigIntegers USING [Sign], IO USING [int, PutFR], Rope USING [Cat, Fetch, ROPE, Substr], SaffronErrorHandling USING [InternalError]; BigIntegersImpl: CEDAR PROGRAM IMPORTS BigCardinals, IO, Rope, SaffronErrorHandling EXPORTS BigIntegers = BEGIN BigINT: TYPE = REF BigINTBody; BigINTBody: PUBLIC TYPE = RECORD [ sign: Sign, absoluteValue: BigCardinals.BigCARD ]; Sign: TYPE = BigIntegers.Sign; BigFromRope: PUBLIC PROC [text: Rope.ROPE, base: [2..36] _ 10] RETURNS [BigINT] ~ BEGIN sign: Sign _ plus; absoluteValue: BigCardinals.BigCARD; SELECT text.Fetch[0] FROM '+ => {text _ text.Substr[1]}; '- => {text _ text.Substr[1]; sign _ minus}; ENDCASE => NULL; SELECT base FROM 2 => {absoluteValue _ BigCardinals.BigFromBinaryRope[text]}; 10 => {absoluteValue _ BigCardinals.BigFromDecimalRope[text]}; ENDCASE => { ERROR SaffronErrorHandling.InternalError[IO.PutFR["Can't parse base %g", IO.int[base]]] }; RETURN[NEW[BigINTBody _ [sign, absoluteValue]]]; END; RopeFromBig: PUBLIC PROC [big: BigINT, base: [2..36] _ 10] RETURNS [Rope.ROPE] ~ BEGIN RETURN[Rope.Cat[ IF big.sign = minus THEN "-" ELSE "", SELECT base FROM 10 => BigCardinals.BigToDecimalRope[big.absoluteValue], ENDCASE => ERROR SaffronErrorHandling.InternalError[IO.PutFR["Can't parse base %g", IO.int[base]]] ]]; END; BigFromSmall: PUBLIC PROC [small: INT] RETURNS [BigINT] ~ BEGIN RETURN[NEW[BigINTBody _ [ sign: IF small >= 0 THEN plus ELSE minus, absoluteValue: BigCardinals.BigFromSmall[ABS[small]] ]]]; END; Add: PUBLIC PROC [big1, big2: BigINT] RETURNS [BigINT] ~ BEGIN abs1: BigCardinals.BigCARD = big1.absoluteValue; abs2: BigCardinals.BigCARD = big2.absoluteValue; RETURN[NEW[BigINTBody _ IF big1.sign = big2.sign THEN [big1.sign, BigCardinals.BigAdd[abs1, abs2]] ELSE SELECT BigCardinals.BigCompare[abs1, abs2] FROM less => [big2.sign, BigCardinals.BigSubtract[abs2, abs1]], equal => [plus, BigCardinals.Zero], greater => [big1.sign, BigCardinals.BigSubtract[abs1, abs2]] ENDCASE => ERROR ]]; END; Sub: PUBLIC PROC [big1, big2: BigINT] RETURNS [BigINT] ~ BEGIN abs1: BigCardinals.BigCARD = big1.absoluteValue; abs2: BigCardinals.BigCARD = big2.absoluteValue; RETURN[NEW[BigINTBody _ IF big1.sign # big2.sign THEN [big1.sign, BigCardinals.BigAdd[abs1, abs2]] ELSE SELECT BigCardinals.BigCompare[abs1, abs2] FROM less => [FlipSign[big1.sign], BigCardinals.BigSubtract[abs2, abs1]], equal => [plus, BigCardinals.Zero], greater => [big1.sign, BigCardinals.BigSubtract[abs1, abs2]] ENDCASE => ERROR ]]; END; Mul: PUBLIC PROC [big1, big2: BigINT] RETURNS [BigINT] ~ BEGIN RETURN[NEW[BigINTBody _ [ sign: IF big1.sign = big2.sign THEN plus ELSE minus, absoluteValue: BigCardinals.BigMultiply[big1.absoluteValue, big2.absoluteValue] ]]]; END; Div: PUBLIC PROC [big1, big2: BigINT] RETURNS [BigINT] ~ BEGIN RETURN[NEW[BigINTBody _ [ sign: IF big1.sign = big2.sign THEN plus ELSE minus, absoluteValue: BigCardinals.BigDivMod[big1.absoluteValue, big2.absoluteValue].quo ]]]; END; Mod: PUBLIC PROC [big1, big2: BigINT] RETURNS [BigINT] ~ BEGIN RETURN[NEW[BigINTBody _ [ sign: IF big1.sign = big2.sign THEN plus ELSE minus, absoluteValue: BigCardinals.BigDivMod[big1.absoluteValue, big2.absoluteValue].rem ]]]; END; Neg: PUBLIC PROC [big1: BigINT] RETURNS [BigINT] ~ BEGIN RETURN[IF BigCardinals.BigZero[big1.absoluteValue] THEN big1 ELSE NEW[BigINTBody _ [ sign: FlipSign[big1.sign], absoluteValue: big1.absoluteValue ]]]; END; FlipSign: PROC [sign: Sign] RETURNS [Sign] = INLINE { RETURN[IF sign = plus THEN minus ELSE plus]; }; MultiplySigns: PROC [sign1, sign2: Sign] RETURNS[Sign] = INLINE { RETURN[IF sign1 = sign2 THEN plus ELSE minus]; }; Abs: PUBLIC PROC [big1: BigINT] RETURNS [BigCardinals.BigCARD] ~ BEGIN RETURN [big1.absoluteValue]; END; Sgn: PUBLIC PROC [big1: BigINT] RETURNS [Sign] ~ BEGIN RETURN [big1.sign]; END; BigFromBigCARD: PUBLIC PROC [bc: BigCardinals.BigCARD, sign: Sign] RETURNS [BigINT] ~ BEGIN IF BigCardinals.BigZero[bc] THEN RETURN [NEW[BigINTBody _ [plus, bc]]] ELSE RETURN [NEW[BigINTBody _ [sign, bc]]]; END; END. μBigIntegersImpl.Mesa Copyright Σ 1988 by Xerox Corporation. All rights reserved. James Rauen, June 20, 1988 4:34:50 pm PDT James Rauen, July 16, 1988 5:11:25 pm PDT SmallFromBig: PUBLIC PROC [big: BigINT] RETURNS [INT] ~ BEGIN ΚΦ˜™Icode™˜>Jšœ@˜@šœ˜ Jšœ$œœ˜Z——Jšœœ&˜0Jšœ˜J˜—š ž œœœ#œœ˜Všœ ˜Jšœœœ˜%šœ˜Jšœ9˜9šœ˜ Jšœ$œœ ˜W——J˜—Jšœ˜—K˜š ž œœœ œœ ˜?šœœ˜Jšœœ œœ˜)Jšœ)œ˜4J˜—Jšœ˜K˜—Kš ž œœœœœ™=K˜š žœœœœ ˜>Jšœ0˜0Jšœ0˜0šœœ ˜šœ˜Jšœ-˜1šœœ%˜4Jšœ;˜;J˜$Jšœ<˜Jšœ0˜0Jšœ0˜0šœœ ˜šœ˜Jšœ-˜1šœœ%˜4JšœE˜EJ˜$Jšœ<˜šœœ˜Jšœœœœ˜4JšœO˜OJ˜—Jšœ˜J˜—š žœœœœ ˜>šœœ˜Jšœœœœ˜4JšœQ˜QJ˜—Jšœ˜J˜—š žœœœœ ˜>šœœ˜Jšœœœœ˜4JšœQ˜QJ˜—Jšœ˜J˜—š žœœœœ ˜8šœœ*˜3Jšœ˜ šœœ˜Jšœ˜Jšœ!˜!J˜——Jšœ˜—K˜šžœœœ œ˜5Jšœœ œœ ˜/J˜—šž œœœ œ˜AJšœœœœ ˜1J˜—š žœœœœ˜FKšœ˜Kšœ˜K˜—š žœœœœ œ˜7Kšœ ˜Kšœ˜K˜—š žœœœ(œ ˜[šœ˜Kšœœœ˜*Kšœœœ˜+—Kšœ˜—K˜Kšœ˜—K™—…—„F