(* ---------------------------------------------------------------------------- * $Id: MASRN.mi,v 1.3 1992/10/15 16:28:15 kredel Exp $ * ---------------------------------------------------------------------------- * This file is part of MAS. * ---------------------------------------------------------------------------- * Copyright (c) 1989 - 1992 Universitaet Passau * ---------------------------------------------------------------------------- * $Log: MASRN.mi,v $ * Revision 1.3 1992/10/15 16:28:15 kredel * Changed rcsid variable * * Revision 1.2 1992/02/12 13:19:05 pesch * Moved CONST Definition to the right place. * * Revision 1.1 1992/01/22 15:08:32 kredel * Initial revision * * ---------------------------------------------------------------------------- *) IMPLEMENTATION MODULE MASRN; (* MAS Rational Number Implemantation Module. *) (* Import lists and declarations. *) FROM MASELEM IMPORT MASEXP; FROM MASSTOR IMPORT LIST, SIL, FIRST, RED, ADV, INV, COMP, BETA, LENGTH; FROM MASBIOS IMPORT CWRITE, DIGIT, BKSP, BLINES, SOLINE, MASORD, CREAD, CREADB, SWRITE; FROM SACLIST IMPORT EQUAL, CINV, ADV2, FIRST2, CLOUT; FROM SACD IMPORT ETA, THETA; FROM SACI IMPORT ICOMP, IQR, IPROD, INEG, ISIGNF, IEXP, ISUM, IDPR, IWRITE, IREAD; FROM SACRN IMPORT RNSIGN, RNPROD, RNCOMP, RNSUM, RNINT, RNRED, RNDIF, RNWRIT; CONST rcsidi = "$Id: MASRN.mi,v 1.3 1992/10/15 16:28:15 kredel Exp $"; CONST copyrighti = "Copyright (c) 1989 - 1992 Universitaet Passau"; PROCEDURE RNDRD(): LIST; (*Rational number decimal read. The rational number R is read from the input stream. Any preceding blanks are skipped.*) VAR A, B, BL, BLP, C, IL, J1Y, JL, R, R1, R2, RP, s: LIST; BEGIN (*1*) (*rational number read. *) C:=CREADB(); BKSP; IF C = MASORD("-") THEN s:=-1 ELSE s:=1 END; R1:=IREAD(); C:=CREADB(); IF C <> MASORD(".") THEN IF C = MASORD("/") THEN R2:=IREAD(); ELSE R2:=1; BKSP; END; R:=RNRED(R1,R2); RETURN(R); END; (*2*) (*read decimal fraction. *) JL:=-1; REPEAT C:=CREADB(); JL:=JL+1; UNTIL C <> 0; (*3*) (*fraction=0.*) IF NOT DIGIT(C) THEN BKSP; R:=RNINT(R1); RETURN(R); END; A:=0; (*4*) (*compute theta-digits.*) B:=BETA; BL:=0; IL:=0; REPEAT J1Y:=10*BL; BL:=J1Y+C; IL:=IL+1; IF IL = ETA THEN B:=COMP(BL,B); BL:=0; IL:=0; END; JL:=JL+1; C:=CREAD(); UNTIL NOT DIGIT(C); BKSP; (*5*) (*convert to base beta.*) B:=INV(B); WHILE B <> SIL DO A:=IDPR(A,THETA); ADV(B, BLP,B); A:=ISUM(A,BLP); END; IF A <> 0 THEN J1Y:=MASEXP(10,IL); A:=IDPR(A,J1Y); END; A:=ISUM(A,BL); R2:=IEXP(10,JL); R:=RNRED(A,R2); RP:=RNINT(R1); IF s < 0 THEN R:=RNDIF(RP,R) ELSE R:=RNSUM(RP,R) END; RETURN(R); (*8*) END RNDRD; PROCEDURE RNDWR(R,NL: LIST); (*Rational number decimal write. R is a rational number. n is a non-negative integer. R is approximated by a decimal fraction D with n decimal digits following the decimal point and D is written in the output stream. The inaccuracy of the approximation is at most (1/2)*10**-n. *) VAR A, B, D, DL, F, IL, M, SL, TL: LIST; BEGIN (*1*) (*compute approximation.*) IF R = 0 THEN A:=0; B:=1; ELSE FIRST2(R, A,B); END; SL:=ISIGNF(A); IF SL < 0 THEN A:=INEG(A); END; M:=IEXP(10,NL); A:=IPROD(A,M); IQR(A,B, D,F); F:=IDPR(F,2); IF F = 0 THEN TL:=0; ELSE TL:=ICOMP(B,F); IF TL = 0 THEN TL:=1; ELSE IF TL < 0 THEN D:=ISUM(D,1); END; END; END; (*2*) (*convert and write.*) IF SL < 0 THEN SWRITE("-"); END; IQR(D,M, D,F); IWRITE(D); SWRITE("."); FOR IL:=1 TO NL DO F:=IDPR(F,10); IQR(F,M, DL,F); CWRITE(DL); END; RETURN; (*5*) END RNDWR; PROCEDURE RNDWRS(A,S: LIST); (*Rational number decimal write special. Call RNDWR. *) BEGIN (*1*) RNDWR(A,S); RETURN; (*4*) END RNDWRS; PROCEDURE RNEXP(A,NL: LIST): LIST; (*Rational number exponentiation. A is a rational number, n is a non-negative beta-integer. B=A**n.*) VAR B, KL: LIST; BEGIN (*1*) (*nl less than or equal to 1.*) IF NL = 0 THEN B:=RNINT(1); RETURN(B); END; IF NL = 1 THEN B:=A; RETURN(B); END; (*2*) (*recursion.*) KL:=NL DIV 2; B:=RNEXP(A,KL); B:=RNPROD(B,B); IF NL > 2*KL THEN B:=RNPROD(B,A); END; RETURN(B); (*5*) END RNEXP; PROCEDURE RNMAX(AL,BL: LIST): LIST; (*Rational number maximum. a and b are rational numbers. c is the maximum of a and b.*) VAR CL, SL: LIST; BEGIN (*1*) SL:=RNCOMP(AL,BL); IF SL >= 0 THEN CL:=AL; ELSE CL:=BL; END; RETURN(CL); (*4*) END RNMAX; PROCEDURE RNONE(R: LIST): LIST; (*Rational number one. R is a rational number. s=1 if R=1, s=0 else. *) VAR R1, R2, SL: LIST; BEGIN (*1*) (*denominator=numerator. *) SL:=0; IF R = 0 THEN RETURN(SL); END; FIRST2(R, R1,R2); SL:=EQUAL(R1,R2); (*4*) RETURN(SL); END RNONE; END MASRN. (* -EOF- *)