PACKAGE BODY Rationals IS
------------------------------------------------------------------
--|
--| Body of the abstract data type for representing
--| and manipulating rational numbers.
--|
--| Author: Michael B. Feldman, The George Washington University
--| Last Modified: July 1995
--|
------------------------------------------------------------------
-- local function GCD, not provided to clients
FUNCTION GCD(M: Positive; N: Positive) RETURN Positive IS
-- finds the greatest common divisor of M and N
-- Pre: M and N are defined
-- Post: returns the GCD of M and N, by Euclid's Algorithm
R : Natural;
TempM: Positive;
TempN: Positive;
BEGIN -- GCD
TempM := M;
TempN := N;
R := TempM REM TempN;
WHILE R /= 0 LOOP
TempM := TempN;
TempN := R;
R := TempM REM TempN;
END LOOP;
RETURN TempN;
END GCD;
-- exported operations
FUNCTION "/" (X : Integer; Y : Integer) RETURN Rational IS
G: Positive;
BEGIN -- "/"
IF Y = 0 THEN
RAISE ZeroDenominator;
END IF;
IF X = 0 THEN
RETURN (Numerator => 0, Denominator => 1);
END IF;
G := GCD(ABS X, ABS Y);
IF Y > 0 THEN
RETURN (Numerator => X/G, Denominator => Y/G);
ELSE
RETURN (Numerator => (-X)/G, Denominator => (-Y)/G);
END IF;
END "/";
-- selectors
FUNCTION Numer (R : Rational) RETURN Integer IS
BEGIN -- Numer
RETURN R.Numerator;
END Numer;
FUNCTION Denom (R : Rational) RETURN Positive IS
BEGIN -- Denom
RETURN R.Denominator;
END Denom;
-- inquiry operators
FUNCTION "<" (R1 : Rational; R2 : Rational) RETURN Boolean IS
BEGIN
RETURN Numer(R1) * Denom(R2) < Numer(R2) * Denom(R1);
END "<";
FUNCTION ">" (R1 : Rational; R2 : Rational) RETURN Boolean IS
BEGIN -- stub
RETURN True;
END ">";
FUNCTION "<=" (R1 : Rational; R2 : Rational) RETURN Boolean IS
BEGIN -- stub
RETURN True;
END "<=";
FUNCTION ">=" (R1 : Rational; R2 : Rational) RETURN Boolean IS
BEGIN -- stub
RETURN True;
END ">=";
-- monadic arithmetic operators
FUNCTION "+"(R : Rational) RETURN Rational IS
BEGIN -- "+"
RETURN R;
END "+";
FUNCTION "-"(R : Rational) RETURN Rational IS
BEGIN -- "-"
RETURN (-Numer(R)) / Denom(R);
END "-";
FUNCTION "ABS"(R : Rational) RETURN Rational IS
BEGIN -- "ABS"
RETURN (ABS Numer(R)) / Denom(R);
END "ABS";
-- dyadic arithmetic operators
FUNCTION "+"(R1 : Rational; R2 : Rational) RETURN Rational IS
N: Integer;
D: Positive;
BEGIN -- "+"
N := Numer(R1) * Denom(R2) + Numer(R2) * Denom(R1);
D := Denom(R1) * Denom(R2);
RETURN N/D; -- compiler will use Rational constructor here!
END "+";
FUNCTION "*"(R1 : Rational; R2 : Rational) RETURN Rational IS
N: Integer;
D: Positive;
BEGIN
N := Numer(R1) * Numer(R2);
D := Denom(R1) * Denom(R2);
RETURN N/D; -- compiler will use Rational constructor here!
END "*";
FUNCTION "-"(R1 : Rational; R2 : Rational) RETURN Rational IS
BEGIN -- stub
RETURN 1/1;
END "-";
FUNCTION "/"(R1 : Rational; R2 : Rational) RETURN Rational IS
BEGIN -- stub
RETURN 1/1;
END "/";
END Rationals;