(* ---------------------------------------------------------------------------- * $Id: SACD.mi,v 1.3 1992/10/15 16:28:17 kredel Exp $ * ---------------------------------------------------------------------------- * This file is part of MAS. * ---------------------------------------------------------------------------- * Copyright (c) 1989 - 1992 Universitaet Passau * ---------------------------------------------------------------------------- * $Log: SACD.mi,v $ * Revision 1.3 1992/10/15 16:28:17 kredel * Changed rcsid variable * * Revision 1.2 1992/02/12 13:19:10 pesch * Moved CONST Definition to the right place. * * Revision 1.1 1992/01/22 15:08:38 kredel * Initial revision * * ---------------------------------------------------------------------------- *) IMPLEMENTATION MODULE SACD; (* SAC Digit Implementation Module. *) (* Import lists and Definitions *) FROM MASELEM IMPORT MASABS, MASEVEN, MASQREM, MASREM, MASSIGN; FROM MASSTOR IMPORT BETA, SIL, LIST, COMP, ADV; FROM SACLIST IMPORT CONC, LIST10; VAR RINC, RMULT, RTERM: LIST; CONST rcsidi = "$Id: SACD.mi,v 1.3 1992/10/15 16:28:17 kredel Exp $"; CONST copyrighti = "Copyright (c) 1989 - 1992 Universitaet Passau"; PROCEDURE BEGIN2; (*BEGIN2 calls BEGIN1 and then initializes the system globals for the arithmetic system.*) VAR IL, J1Y, J2Y, L, ML, TL: LIST; BEGIN (*1*) (*call begin1.*) (*BEGIN1; not required with modula-2*) (*2*) (*compute zeta, eta, theta, delta, epsil and tabp2 elements.*) IL:=1; TL:=1; WHILE TL < BETA DO TABP2[INTEGER(IL)]:=TL; IL:=IL+1; TL:=TL+TL; END; ZETA:=IL-1; ETA:=0; TL:=BETA; REPEAT TL:=TL DIV 10; ETA:=ETA+1; UNTIL TL < 10; THETA:=1; FOR IL:=1 TO ETA DO THETA:=10*THETA; END; J1Y:=ZETA DIV 2; J1Y:=J1Y+1; DELTA:=TABP2[INTEGER(J1Y)]; EPSIL:=BETA DIV DELTA; (*3*) (*compute rmult, rinc and rterm.*) J1Y:=LIST10(3,1,4,1,5,9,2,6,5,3); J2Y:=LIST10(5,8,9,7,9,3,2,3,8,4); L:=CONC(J1Y,J2Y); ML:=0; WHILE ML < (BETA DIV 10) DO ADV(L,TL,L); J1Y:=10*ML; ML:=J1Y+TL; END; ML:=ML DIV 8; J1Y:=8*ML; RMULT:=J1Y+5; J1Y:=LIST10(2,1,1,3,2,4,8,6,5,4); J2Y:=LIST10(0,5,1,8,7,1,0,0,0,0); L:=CONC(J1Y,J2Y); ML:=0; FOR IL:=1 TO ETA DO ADV(L,TL,L); J1Y:=10*ML; ML:=J1Y+TL; END; DQR(ML,0,THETA,RINC,TL); IF MASEVEN(RINC) THEN RINC:=RINC+1; END; J1Y:=LIST10(5,7,7,2,1,5,6,6,4,9); J2Y:=LIST10(0,1,5,3,2,8,6,0,6,0); L:=CONC(J1Y,J2Y); ML:=0; FOR IL:=1 TO ETA DO ADV(L,TL,L); J1Y:=10*ML; ML:=J1Y+TL; END; RTERM:=ML; (*8*) RETURN; END BEGIN2; PROCEDURE BITRAN(): LIST; (*Bit, random. b is a random bit, 0 or 1.*) VAR AL, BL, IDUM: LIST; BEGIN (*1*) AL:=DRANN(); AL:=AL+AL; IF AL >= BETA THEN BL:=1; ELSE BL:=0; END; RETURN(BL); (*4*) END BITRAN; PROCEDURE DEGCD(AL,BL: LIST; VAR CL,UL,VL: LIST); (*Digit extended greatest common divisor. a and b are beta-integers, a ge b ge 0. c=GCD(a,b), a beta-integer. a*u+b*v=c, with ABS(u) le b/2c, ABS(v) le a/2c.*) VAR AL1, AL2, AL3, J1Y, QL, UL1, UL2, UL3, VL1, VL2, VL3: LIST; BEGIN (*1*) AL1:=AL; AL2:=BL; UL1:=1; UL2:=0; VL1:=0; VL2:=1; WHILE AL2 <> 0 DO MASQREM(AL1,AL2,QL,AL3); AL1:=AL2; AL2:=AL3; J1Y:=QL*UL2; UL3:=UL1-J1Y; UL1:=UL2; UL2:=UL3; J1Y:=QL*VL2; VL3:=VL1-J1Y; VL1:=VL2; VL2:=VL3; END; CL:=AL1; UL:=UL1; VL:=VL1; RETURN; (*4*) END DEGCD; PROCEDURE DGCD(AL,BL: LIST): LIST; (*Digit greatest common divisor. a and b are beta-integers, a ge b ge 0. c=GCD(a,b).*) VAR AL1, AL2, AL3, CL: LIST; BEGIN (*1*) AL1:=AL; AL2:=BL; WHILE AL2 <> 0 DO AL3:=MASREM(AL1,AL2); AL1:=AL2; AL2:=AL3; END; CL:=AL1; RETURN(CL); (*4*) END DGCD; PROCEDURE DLOG2(AL: LIST): LIST; (*Digit logarithm, base 2. a is a beta-digit. If a=0 then n=0. otherwise n=FLOOR(LOG2(ABS(a)))+1.*) VAR ALB, IL, J1Y, JL, NL: LIST; BEGIN (*1*) (*al le 0.*) IF AL = 0 THEN NL:=0; RETURN(NL); END; ALB:=MASABS(AL); (*2*) (*binary search.*) IL:=1; JL:=ZETA+1; REPEAT J1Y:=IL+JL; NL:=J1Y DIV 2; IF ALB >= TABP2[INTEGER(NL)] THEN IL:=NL; ELSE JL:=NL; END; UNTIL JL-IL = 1; NL:=IL; RETURN(NL); (*5*) END DLOG2; PROCEDURE DPCC(AL1,AL2: LIST; VAR UL,ULP,VL,VLP: LIST); (*Digit partial cosequence calculation. a1 and a2 are beta-integers, a1 ge a2 gt 0. u, up, v and vp are the last cosequence elements of a1 and a2 which can be guaranteed to correspond to correct quotient digits.*) VAR AL, ALP, ALPP, J1Y, QL, ULPP, VLPP: LIST; BEGIN (*1*) AL:=AL1; ALP:=AL2; UL:=1; ULP:=0; VL:=0; VLP:=1; LOOP QL:=AL DIV ALP; J1Y:=QL*ALP; ALPP:=AL-J1Y; J1Y:=QL*ULP; ULPP:=UL-J1Y; J1Y:=QL*VLP; VLPP:=VL-J1Y; IF (ALPP < MASABS(VLPP)) OR (ALP-ALPP < MASABS(VLP-VLPP)) THEN RETURN; END; AL:=ALP; ALP:=ALPP; UL:=ULP; ULP:=ULPP; VL:=VLP; VLP:=VLPP; END; (*4*) RETURN; END DPCC; PROCEDURE DPR(AL,BL: LIST; VAR CL,DL: LIST); (*Digit product. a and b are beta-digits. c and d are the unique beta-digits such that a*b=c*beta+d and c*d ge 0.*) VAR AL0, AL1, BL0, BL1, CL0, CL00, CL01, CL1, CL10, CL11, CL2, CLP, DLP, J1Y, J2Y: LIST; BEGIN (*1*) AL1:=AL DIV EPSIL; J1Y:=AL1*EPSIL; AL0:=AL-J1Y; BL1:=BL DIV EPSIL; J1Y:=BL1*EPSIL; BL0:=BL-J1Y; (*2*) CL0:=AL0*BL0; J1Y:=AL1*BL0; J2Y:=AL0*BL1; CL1:=J1Y+J2Y; CL2:=AL1*BL1; (*3*) IF CL0 >= BETA THEN CL01:=1; CL00:=CL0-BETA; ELSE IF CL0 <= -BETA THEN CL01:=-1; CL00:=CL0+BETA; ELSE CL01:=0; CL00:=CL0; END; END; CL11:=CL1 DIV DELTA; J1Y:=CL11*DELTA; CL10:=CL1-J1Y; (*4*) J1Y:=CL2+CL01; CLP:=J1Y+CL11; IF DELTA <> EPSIL THEN CLP:=CLP+CL2; END; J1Y:=CL10*EPSIL; DLP:=J1Y+CL00; (*5*) IF DLP >= BETA THEN CL:=CLP+1; DL:=DLP-BETA; ELSE IF DLP <= -BETA THEN CL:=CLP-1; DL:=DLP+BETA; ELSE CL:=CLP; DL:=DLP; END; END; RETURN; (*8*) END DPR; PROCEDURE DQR(AL1,AL0,BL: LIST; VAR QL,RL: LIST); (*Digit quotient and remainder. a1, a0 and b are beta-integers with a1*a0 ge 0 and ABS(b) gt ABS(a1). q is the integral part of (a1*beta+a0)/b and r is (a1*beta+a0)-b*q. q and r are beta-integers.*) VAR ALP0, ALP1, BLP, QLP: LIST; IL: INTEGER; BEGIN (*1*) (*al1 eq 0.*) IF AL1 = 0 THEN MASQREM(AL0,BL,QL,RL); RETURN; END; (*2*) (*compute absolute values.*) ALP1:=MASABS(AL1); ALP0:=MASABS(AL0); BLP:=MASABS(BL); (*3*) (*shift and subtract.*) QLP:=0; FOR IL:=1 TO INTEGER(ZETA) DO ALP1:=ALP1+ALP1; ALP0:=ALP0+ALP0; IF ALP0 >= BETA THEN ALP0:=ALP0-BETA; ALP1:=ALP1+1; END; QLP:=QLP+QLP; IF ALP1 >= BLP THEN ALP1:=ALP1-BLP; QLP:=QLP+1; END; END; (*4*) (*compute signs.*) IF AL1 < 0 THEN QLP:=-QLP; ALP1:=-ALP1; END; IF BL < 0 THEN QLP:=-QLP; END; QL:=QLP; RL:=ALP1; RETURN; (*7*) END DQR; PROCEDURE DRAN(): LIST; (*Digit, random. a is a random beta-digit.*) VAR AL, AL1, AL2, IDUM, J1Y, SL: LIST; BEGIN (*1*) AL1:=DRANN(); SL:=0; AL1:=AL1+AL1; IF AL1 >= BETA THEN SL:=1; AL1:=AL1-BETA; END; AL1:=AL1 DIV DELTA; AL2:=DRANN(); AL2:=AL2 DIV EPSIL; J1Y:=AL1*DELTA; AL:=J1Y+AL2; IF SL = 1 THEN AL:=-AL; END; RETURN(AL); (*4*) END DRAN; PROCEDURE DRANN(): LIST; (*Digit, random non-negative. a is a random non-negative beta-digit. Caution, the low-order bits of a are not very random.*) VAR AL, TL: LIST; BEGIN (*1*) DPR(RTERM,RMULT,TL,AL); AL:=AL+RINC; IF AL >= BETA THEN AL:=AL-BETA; END; RTERM:=AL; RETURN(AL); (*4*) END DRANN; PROCEDURE DSQRTF(AL: LIST; VAR BL,TL: LIST); (*Digit square root function. a is a non-negative beta-integer. b is the floor function of the square root of a and t is the sign of a-b*b.*) VAR CL, HL, J1Y, KL, RL: LIST; BEGIN (*1*) (*al=0.*) IF AL = 0 THEN BL:=0; TL:=0; RETURN; END; (*2*) (*compute first approximation.*) KL:=DLOG2(AL); J1Y:=KL+1; HL:=J1Y DIV 2; BL:=TABP2[INTEGER(HL)+1]; (*3*) (*iterate modified newton method.*) LOOP MASQREM(AL,BL,CL,RL); IF BL <= CL THEN J1Y:=BL*BL; J1Y:=AL-J1Y; TL:=MASSIGN(J1Y); RETURN; END; J1Y:=BL+CL; BL:=J1Y DIV 2; END; (*loop*) RETURN; (*6*) END DSQRTF; BEGIN (* Initialization. *) BEGIN2; END SACD. (* -EOF- *)