Category : Files from Magazines
Archive   : VOL9N10.ZIP
Filename : NUMBERS.PAS

 
Output of file : NUMBERS.PAS contained in archive : VOL9N10.ZIP
UNIT numbers;

(********************)
(**) INTERFACE (**)
(********************)

CONST POOLSIZE = 128;

TYPE
NumberPtr = ^Number;
NPPtr = ^NumberPool;
Number = object
np : NPPtr;
CONSTRUCTOR init(iNp : NPPtr);
DESTRUCTOR done;
FUNCTION im : Real; virtual;
FUNCTION re : Real; virtual;
FUNCTION equal(VAR nv : Number) : Boolean; virtual;
FUNCTION numer : Integer; virtual;
FUNCTION denom : Integer; virtual;
PROCEDURE error(s : STRING);
PROCEDURE cleanup;
FUNCTION GetPool : NPPtr;
END;

ComplexPtr = ^Complex;
Complex = object(Number)
a, b : Real;
CONSTRUCTOR init(x, y : Real; iNp : NPPtr);
CONSTRUCTOR initFrom(VAR nv : complex);
CONSTRUCTOR ReadLn(iNp : NPPtr);
DESTRUCTOR done;
FUNCTION im : Real; virtual;
FUNCTION re : Real; virtual;
FUNCTION equal(VAR nv : Number) : Boolean; virtual;
FUNCTION asString : STRING;
FUNCTION plus(VAR nv : Number) : ComplexPtr;
FUNCTION minus(VAR nv : Number) : ComplexPtr;
FUNCTION times(VAR nv : Number) : ComplexPtr;
FUNCTION divBy(VAR nv : Number) : ComplexPtr;
END;

RationalPtr = ^Rational;
Rational = object(Number)
n, d : LongInt;
CONSTRUCTOR init(x, y : LongInt; iNp : NPPtr);
CONSTRUCTOR InitFrom(VAR nv : Rational);
CONSTRUCTOR ReadLn(iNp : NPPtr);
DESTRUCTOR done;
FUNCTION re : Real; virtual;
FUNCTION im : Real; virtual;
FUNCTION equal(VAR nv : Number) : Boolean; virtual;
FUNCTION numer : Integer; virtual;
FUNCTION denom : Integer; virtual;
FUNCTION asString : STRING;
FUNCTION plus (VAR nv : Number) : RationalPtr;
FUNCTION minus(VAR nv : Number) : RationalPtr;
FUNCTION times(VAR nv : Number) : RationalPtr;
FUNCTION divBy(VAR nv : Number) : RationalPtr;
PROCEDURE reduce;
END;

Pool = object
p : ARRAY[1..POOLSIZE] OF NumberPtr;
ixcur : 1..POOLSIZE;
PROCEDURE init;
PROCEDURE gc;
END;

NumberPool = object(Pool)
FUNCTION newComplexPtr(x, y : Real) : ComplexPtr;
FUNCTION newRationalPtr(x, y : LongInt) : RationalPtr;
END;

(********************)
(**)IMPLEMENTATION(**)
(********************)

PROCEDURE Pool.init; BEGIN ixcur := 1; END;

PROCEDURE Pool.gc; {Garbage Collection}
VAR i : Integer;
BEGIN
FOR i := 1 TO ixcur-1 DO Dispose(p[i],done);
ixcur := 1;
END;

FUNCTION NumberPool.newComplexPtr(x, y : Real) : ComplexPtr;
BEGIN
p[ixcur] := New(ComplexPtr, init(x, y, @self));
newComplexPtr := ComplexPtr(p[ixcur]);
Inc(ixcur);
END;

FUNCTION NumberPool.newRationalPtr(x, y : LongInt) : RationalPtr;
BEGIN
p[ixcur] := New(RationalPtr, init(x, y, @self));
newRationalPtr := RationalPtr(p[ixcur]);
Inc(ixcur);
END;

(************* Methods for Object: Number ************)

constructor Number.init(iNp : NPPtr); BEGIN np := iNp; END;

DESTRUCTOR Number.done; BEGIN END;

PROCEDURE Number.error(s : STRING);
BEGIN
WriteLn('Error in class "Number": ', s);
Halt(1);
END;

FUNCTION Number.im : Real; BEGIN error('im'); END;

FUNCTION Number.re : Real; BEGIN error('re'); END;

FUNCTION Number.numer : Integer; BEGIN error('numer'); END;

FUNCTION Number.denom : Integer; BEGIN error('denom'); END;

FUNCTION Number.equal(VAR nv : Number) : Boolean;
BEGIN error('equal') END;

PROCEDURE Number.Cleanup; BEGIN np^.gc; END;

FUNCTIOn Number.GetPool : NPPtr; BEGIN GetPool := np; END;

(************* Methods for Object: Complex ***********)

CONSTRUCTOR Complex.init(x, y : Real; iNp : NPPtr);
BEGIN a := x; b := y; Number.Init(iNp); END;

CONSTRUCTOR complex.initFrom(VAR nv : Complex);
BEGIN Init(nv.re, nv.im, nv.getpool); END;

CONSTRUCTOR Complex.ReadLn(iNp : NPPtr);
VAR s : STRING;
p, q, err : Integer;
BEGIN
System.ReadLn(s);
p := pos('+', s);
IF p = 0 THEN
BEGIN
p := pos('-',Copy(S,2,pred(length(S))));
IF p > 0 THEN inc(P);
END;
q := pos('i', s);
IF (p = 0) THEN
BEGIN
IF q <> 0 THEN Fail;
Val(s, a, err);
IF err <> 0 THEN Fail;
b := 0;
END
ELSE
BEGIN
IF q = 0 THEN Fail;
Val(Copy(s, 1, p-1), a, err);
IF err <> 0 THEN Fail;
Val(Copy(s, p+1, q-p-1), b, err);
IF err <> 0 THEN Fail;
END;
IF s[p] = '-' THEN b := -b;
init(a, b, np);
END;

DESTRUCTOR Complex.done; BEGIN END;

FUNCTION Complex.im : Real; BEGIN im := b; END;

FUNCTION Complex.re : Real; BEGIN re := a; END;

FUNCTION Complex.equal(VAR nv : Number) : Boolean;
BEGIN equal := (a = nv.re) AND (b = nv.im); END;

FUNCTION Complex.asString : STRING;
VAR ret, s : STRING;
BEGIN
Str(a:1:2, ret); Str(abs(b):1:2, s);
IF b < 0 THEN ret := ret+'-'+s+'i'
ELSE ret := ret+'+'+s+'i';
asString := ret;
END;

FUNCTION Complex.plus(VAR nv : Number) : ComplexPtr;
BEGIN
plus := np^.newComplexPtr(a + nv.re, b + nv.im);
END;

FUNCTION Complex.minus(VAR nv : Number) : ComplexPtr;
BEGIN
minus := np^.newComplexPtr(a - nv.re, b - nv.im);
END;

FUNCTION Complex.times(VAR nv : Number) : ComplexPtr;
BEGIN
times := np^.newComplexPtr(a * nv.re - b * nv.im,
a * nv.im + b * nv.re);
END;

FUNCTION Complex.divBy(VAR nv : Number) : ComplexPtr;
VAR m2 : Real;
BEGIN
WITH nv DO m2 := re * re + im * im;
IF (m2 = 0) THEN error('Attempt to divide by 0 in class Complex');
divby := np^.newComplexPtr((a * nv.re + b * nv.im) / m2,
(b * nv.re - a * nv.im) / m2);
END;

(************* Methods for Object: Rational **********)

CONSTRUCTOR Rational.init(x, y : LongInt; iNp : NPPtr);
BEGIN
IF (y = 0) THEN BEGIN
WriteLn('Attempt to init Rational with zero denominator');
Halt(1);
END;
n := x; d := y;
reduce;
Number.Init(iNp);
END;

CONSTRUCTOR Rational.InitFrom(var nv : Rational);
BEGIN Init(nv.numer, nv.denom, nv.getpool); END;

CONSTRUCTOR Rational.ReadLn(iNp : NPPtr);
VAR s : STRING;
p, err : Integer;
BEGIN
System.ReadLn(s);
p := pos('/', s);
IF (p = 0) THEN
BEGIN
Val(s, n, err);
IF err <> 0 THEN Fail;
d := 1;
END
ELSE
BEGIN
Val(Copy(s, 1, p-1), n, err);
IF err <> 0 THEN Fail;
Val(Copy(s, p+1, Length(s)), d, err);
IF err <> 0 THEN Fail;
END;
init(n, d, inp);
END;

DESTRUCTOR rational.done; BEGIN END;

PROCEDURE Rational.reduce;
VAR g : LongInt;

FUNCTION gcd(x, y : LongInt) : LongInt;
VAR r : LongInt;
BEGIN
WHILE (y <> 0) DO
BEGIN
r := x MOD y;
x := y;
y := r
END;
gcd := x;
END;

BEGIN
IF (d < 0) THEN BEGIN d := -d; n := -n; END;
g := gcd(n, d);
IF (g <> 0) AND (g <> 1) AND (g <> -1) THEN
BEGIN
n := n DIV g;
d := d DIV g;
END;
END;

FUNCTION Rational.re : Real; BEGIN re := n/d; END;

FUNCTION Rational.im : Real; BEGIN im := 0; END;

FUNCTION Rational.numer : Integer; BEGIN numer := n; END;

FUNCTION Rational.denom : Integer; BEGIN denom := d; END;

FUNCTION Rational.asString : STRING;
VAR t, u : STRING;
BEGIN
Str(n, t);
IF (d <> 1) THEN
BEGIN Str(d, u); t := t+'/'+u; END;
asString := t;
END;

FUNCTION Rational.plus(VAR nv : Number) : RationalPtr;
BEGIN
plus := np^.newRationalPtr(n * nv.denom + d * nv.numer, d * nv.denom);
END;

FUNCTION Rational.minus(VAR nv : Number) : RationalPtr;
BEGIN
minus := np^.newRationalPtr(n * nv.denom - d * nv.numer, d * nv.denom);
END;

FUNCTION Rational.times(VAR nv : Number) : RationalPtr;
BEGIN
times := np^.newRationalPtr(n * nv.numer, d * nv.denom);
END;

FUNCTION Rational.divBy(VAR nv : Number) : RationalPtr;
BEGIN
IF (nv.numer = 0) THEN BEGIN
WriteLn('Attempt to divide by 0 in class Rational');
Halt(1)
END;
divby := np^.newRationalPtr(n * nv.denom, d * nv.numer);
END;

FUNCTION Rational.equal(VAR nv : Number) : Boolean;
BEGIN
equal := (n = nv.numer) AND (d = nv.denom);
END;

END.



  3 Responses to “Category : Files from Magazines
Archive   : VOL9N10.ZIP
Filename : NUMBERS.PAS

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/