Implementation of Rationals Package

Go to Package Interface

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;