home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
modula2
/
library
/
fst
/
modula3
/
bigcardi.mod
< prev
next >
Wrap
Text File
|
1993-07-28
|
5KB
|
165 lines
IMPLEMENTATION MODULE bigcardinal;
(* Ludewig S. 167, Bearbeitung von großen zahlen
bigcardinal stellt einen ADT fuer grosse natuerliche Zahlen bereit
Bei Überlauf wird als Ergebnis die größtmöglich Zahl
geliefert, ausserdem die Meldung "Überlauf" ausgegben *)
FROM IO IMPORT WrLn,WrCard,WrStr;
FROM InOut IMPORT Write;
FROM Storage IMPORT ALLOCATE,DEALLOCATE,Available;
CONST MaxLng=100; (* 10^MaxLng muß ausreichen für Tyfp CARDINAL *)
TYPE Digit=[0..9];
StoreNo=ARRAY[1..MaxLng] OF Digit;
BigNo=POINTER TO StoreNo;
PROCEDURE Create(VAR Zahl:BigNo);
BEGIN
IF Available(SIZE(BigNo)) THEN
ALLOCATE(Zahl,SIZE(StoreNo))
ELSE
WrStr('Kein Speicherplatz mehr zum creieren !!');
END (* IF *)
END Create;
PROCEDURE InitNo(VAR Zahl:BigNo);
(* intern, Zahl auf null sezuen *)
VAR Index:CARDINAL;
BEGIN
FOR Index:= 1 TO MaxLng DO Zahl^[Index]:=0 END;
END InitNo;
PROCEDURE Put9(VAR Zahl:BigNo);
(* intern, Zahl auf Hoechste darstellbare Zahl setzen *)
VAR Index:CARDINAL;
BEGIN
FOR Index:= 1 TO MaxLng DO
Zahl^[Index]:=9
END; (* FOR *)
END Put9;
PROCEDURE CopyNo(No1:BigNo;VAR No2:BigNo);
(* intern, Wert von No1 nach No2 kopieren *)
BEGIN
No2^:=No1^
END CopyNo;
PROCEDURE Out (Zahl:BigNo);
(* ausgabe der Zahl *)
CONST Blank=' ';
VAR Index:CARDINAL;
FuehrendeNull:BOOLEAN;
BEGIN
FuehrendeNull:=TRUE; (* noch keine Ziffer ausgegeben *)
FOR Index:=1 TO MaxLng DO (* Zahl in Dreiergruppen ausgeben *)
IF FuehrendeNull AND (Zahl^[Index]=0)
AND (Index < MaxLng) THEN
Write(Blank) (* fuehrende Nullen unterdruecken *)
ELSE
WrCard(Zahl^[Index],1);
FuehrendeNull:=FALSE;
END; (* IF *)
IF((MaxLng-Index) MOD 3)=0 THEN (* Dreiergruppen bilden *)
Write(Blank)
END; (* IF *)
END; (* FOR *)
WrLn;
END Out;
PROCEDURE Times10(Zahl1:BigNo;VAR Zahl2:BigNo);
(* Zahl2 erhaelt den zehnfachen Wert von Zahl1 *)
VAR Index:CARDINAL;
BEGIN
IF Zahl1^[1]#0 THEN
WrStr('*** Times10 Ueberlauf ***');
WrLn;
Put9(Zahl2);
ELSE
FOR Index:=2 TO MaxLng DO
Zahl2^[Index-1]:=Zahl1^[Index];
END; (* FOR *)
Zahl2^[MaxLng]:=0;
END; (* IF *)
END Times10;
PROCEDURE Enter(VAR Zahl:BigNo;Wert:CARDINAL);
VAR Index:CARDINAL;
BEGIN
InitNo(Zahl); (* Damit ist die Zahl auf 0 initialisiert *)
Index:=MaxLng;
WHILE Wert>0 DO (* Zahl konverieren, beginnend mit der niedrigsten
Ziffer *)
Zahl^[Index]:=Wert MOD 10;
Wert:=Wert DIV 10;
DEC(Index);
END; (* WHILE *)
END Enter;
PROCEDURE Add(S1,S2:BigNo; VAR Summe:BigNo);
VAR Index,Zwischensumme(* Summe zweier Ziffern *):CARDINAL;
BEGIN
Zwischensumme:=0;
Index:=MaxLng;
WHILE (Index>0) DO (* Ziffernweise von rechts nach links add. *)
Zwischensumme:=S1^[Index] + S2^[Index] + Zwischensumme DIV 10;
(* Übertrag *)
Summe^[Index]:=Zwischensumme MOD 10;
DEC(Index);
END; (* WHILE *)
IF Zwischensumme>9 THEN (* Überlauf in der höchsten Ziffer *)
Put9(Summe);
WrStr('*** Add Überlauf ***');
WrLn;
END; (* IF *)
END Add;
PROCEDURE Mul(F1,F2:BigNo;VAR Produkt:BigNo);
VAR Index:CARDINAL;
Prod:BigNo; (* Zwischenspeicher fuer das Ergebnis *)
BEGIN
ALLOCATE(Prod,SIZE(StoreNo));
InitNo(Prod);
Index:=1; (* 1. Ziffer undgleich 0 suchen *)
WHILE (Index<=MaxLng) AND (F2^[Index]=0) DO
INC(Index)
END; (* WHILE *)
WHILE Index<=MaxLng DO
Times10(Prod,Prod); (* Dezimal-Shift um eine Stelle *)
WHILE F2^[Index]>0 DO (* Multipl. durch wiederh. Add. *)
Add(F1,Prod,Prod);
DEC(F2^[Index]);
END; (* WHILE *)
INC(Index);
END; (* WHILE *)
IF Produkt#NIL THEN DEALLOCATE(Produkt,SIZE(StoreNo)) END;
Produkt:=Prod;
END Mul;
PROCEDURE Power(Base:BigNo;Exp:CARDINAL;VAR isPower:BigNo);
VAR BaseCopy:BigNo;
BEGIN
ALLOCATE(BaseCopy ,SIZE(StoreNo));
CopyNo(Base,BaseCopy); (* Entkopplung Parameter/Relultat *)
Enter(isPower,1);
WHILE Exp>0 DO (* Potenzieren durch wiederh. Multiplizieren *)
Mul(BaseCopy,isPower,isPower);
DEC(Exp);
END; (* WHILE *)
DEALLOCATE(BaseCopy,SIZE(StoreNo));
END Power;
PROCEDURE Tausch(VAR T1,T2:BigNo);
VAR hilf:BigNo;
BEGIN
ALLOCATE(hilf,SIZE(BigNo));
hilf^:=T1^;
T1^:=T2^;
T2^:=hilf^;
DEALLOCATE(hilf,SIZE(BigNo));
END Tausch;
END bigcardinal.