home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / 1987 / 06 / longint.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1987-05-18  |  4.9 KB  |  204 lines

  1. (* -------------------------------------------------- *)
  2. (*                   LONGINT.PAS                      *)
  3. (* impl. beliebig langer positiver Integers in Pascal *)
  4. (* -------------------------------------------------- *)
  5.  
  6. CONST LONGINT_Digits= 150; (* Anz. Stellen f. LONGINT *)
  7.       (* Anzahl Bytes zur internen Darstellung der
  8.          gewuenschten Stellenzahl
  9.          = LONGINT_Digits/log(256):                   *)
  10.       LONGINT_Len   = 63;
  11.  
  12. TYPE  LONGINT = ARRAY[1..LONGINT_Len] OF BYTE;
  13.  
  14. (* -------------------------------------------------- *)
  15. (*  norm. INTEGER in eine LONGINTeger konvertieren:   *)
  16.  
  17. PROCEDURE IntToLong (VAR a: LONGINT; b: INTEGER);
  18.  
  19. VAR i: INTEGER;
  20.  
  21. BEGIN
  22.   FOR i := 3 TO LONGINT_Len DO a[I] := 0;
  23.   a[2] := Hi(b);  a[1] := Lo(b);
  24. END;
  25.  
  26. (* -------------------------------------------------- *)
  27. (*                       a < b ?                      *)
  28.  
  29. FUNCTION LLess (a, b: LONGINT): BOOLEAN;
  30.  
  31. VAR i: INTEGER;
  32.  
  33. BEGIN
  34.   i := LONGINT_Len;  LLess := FALSE;
  35.   WHILE (a[i] = b[i]) AND (i > 1) DO i := Pred(i);
  36.   IF a[i] < b[i] THEN LLess := TRUE;
  37. END;
  38.  
  39. (* -------------------------------------------------- *)
  40. (*                  sum := a + b                      *)
  41.  
  42. PROCEDURE LAdd (VAR sum: LONGINT; a, b: LONGINT);
  43.  
  44. VAR i, j: INTEGER;
  45.     mov : BYTE;
  46.  
  47. BEGIN
  48.   mov := 0;
  49.   FOR i := 1 TO LONGINT_Len DO
  50.   BEGIN
  51.     j := a[i] + b[i] + mov;  sum[i] := Lo(j);
  52.     mov := Hi(j);
  53.   END;
  54. END;
  55.  
  56. (* -------------------------------------------------- *)
  57. (*                  diff := a - b                     *)
  58.  
  59. PROCEDURE LSub (VAR diff: LONGINT; a, b: LONGINT);
  60.  
  61. VAR i: INTEGER;
  62.     one: LONGINT;
  63.  
  64. BEGIN
  65.   (* Zweierlomplement des Subtrahenden b bilden: *)
  66.   FOR i := 1 TO LONGINT_Len DO b[i] := NOT b[i];
  67.   IntToLong(one, 1);  LAdd(b, b, one);
  68.   LAdd(diff, a, b);        (* und zu a addieren! *)
  69. END;
  70.  
  71.  
  72. (* -------------------------------------------------- *)
  73. (*    Links-Shift, entspricht Multiplikation mit 2    *)
  74.  
  75. PROCEDURE LShl (VAR a: LONGINT);
  76.  
  77. VAR i: INTEGER;
  78.     mov, schieb: BYTE;
  79.  
  80. BEGIN
  81.   mov := 0;
  82.   FOR i := 1 TO LONGINT_Len DO
  83.   BEGIN
  84.     schieb := (a[i] SHL 1) + mov;
  85.     mov := a[i] SHR 7;  a[i] := schieb;
  86.   END;
  87. END;
  88.  
  89. (* -------------------------------------------------- *)
  90. (*     Rechts-Shift, entspricht Division durch 2      *)
  91.  
  92. PROCEDURE LShr (VAR a: LONGINT);
  93.  
  94. VAR i: INTEGER;
  95.     mov, schieb: BYTE;
  96.  
  97. BEGIN
  98.   mov := 0;
  99.   FOR i := LONGINT_Len DOWNTO 1 DO
  100.   BEGIN
  101.     schieb := (a[i] SHR 1) + mov;
  102.     mov := a[i] SHL 7;  a[i] := schieb;
  103.   END;
  104. END;
  105.  
  106. (* -------------------------------------------------- *)
  107. (*                 prod := a * b                      *)
  108.  
  109. PROCEDURE LMul (VAR prod: LONGINT; a, b: LONGINT);
  110.  
  111. VAR i, j, x, alen, blen: INTEGER;
  112.  
  113. BEGIN
  114.   IntToLong(prod, 0);
  115.   alen := LONGINT_Len;  blen := LONGINT_Len;
  116.   WHILE (a[alen] = 0) AND (alen > 1) DO
  117.     alen := Pred(alen);
  118.   WHILE (b[blen] = 0) AND (blen > 1) DO
  119.     blen := Pred(blen);
  120.   FOR i := 1 TO alen DO
  121.   BEGIN
  122.     x := 0;
  123.     FOR j := 1 TO blen DO
  124.     BEGIN
  125.       x := a[i] * b[j] + Hi(x) + prod[Pred(i+j)];
  126.       prod[Pred(i+j)] := Lo(x);
  127.     END;
  128.     prod[i+blen] := Hi(x);
  129.   END;
  130. END;
  131.  
  132. (* -------------------------------------------------- *)
  133. (*         quot := a DIV b, rest := a MOD b           *)
  134.  
  135. PROCEDURE LDiv (VAR quot, rest: LONGINT; a, b: LONGINT);
  136.  
  137. VAR p, one: LONGINT;
  138.  
  139. BEGIN
  140.   p := b;  IntToLong(quot, 0);  IntToLong(one, 1);
  141.   REPEAT  LShl(b)  UNTIL NOT LLess(b, a);
  142.   REPEAT
  143.     LShl(quot);  LShr(b);
  144.     IF NOT LLess(a, b) THEN
  145.     BEGIN
  146.       LSub(a, a, b);  LAdd(quot, quot, one);
  147.     END;
  148.   UNTIL NOT LLess(p, b);
  149.   rest := a;
  150. END;
  151.  
  152. (* -------------------------------------------------- *)
  153.  
  154. PROCEDURE LRead (VAR a: LONGINT);
  155.  
  156. VAR i, j, m: INTEGER;
  157.     lin: STRING[LONGINT_Digits];
  158.     mov: BYTE;
  159.  
  160. BEGIN
  161.   IntToLong(a, 0);  ReadLn(lin);  i := 1;
  162.   WHILE i <= Length(lin) DO
  163.   BEGIN
  164.     IF lin[i] IN ['0'..'9'] THEN
  165.       BEGIN
  166.         mov := Ord(lin[i]) - Ord('0');
  167.         FOR j := 1 TO LONGINT_Len DO
  168.         BEGIN
  169.           m := a[j] * 10 + mov;
  170.           a[j] := Lo(m);  mov := Hi(m);
  171.         END;
  172.         i := Succ(i);
  173.       END
  174.     ELSE
  175.       i := Succ(Length(lin));
  176.   END;
  177. END;
  178.  
  179. (* -------------------------------------------------- *)
  180.  
  181. PROCEDURE LWrite (a: LONGINT);
  182.  
  183. VAR i, j, k, m, mov: INTEGER;
  184.     puffer: ARRAY[1..LONGINT_Digits] OF CHAR;
  185.  
  186. BEGIN
  187.   j := LONGINT_Len;  k := 0;
  188.   WHILE a[j] = 0 DO j := Pred(j);
  189.   REPEAT
  190.     k := Succ(k);  mov := 0;
  191.     FOR i := j DOWNTO 1 DO
  192.     BEGIN
  193.       m := a[i] + mov * 256;
  194.       a[i] := m DIV 10;  mov := m MOD 10;
  195.     END;
  196.     puffer[k] := CHAR(Ord('0') + mov);
  197.     IF a[j] = 0 THEN j := Pred(j);
  198.   UNTIL j = 0;
  199.   FOR i := k DOWNTO 1 DO Write(puffer[i]);
  200. END;
  201.  
  202. (* -------------------------------------------------- *)
  203. (*              Ende von LONGINT.PAS                  *)
  204.