Rem
Rem Rational.sql
Rem
Rem  Copyright (c) Oracle Corporation 1999. All Rights Reserved.
Rem

/*** Using object types via JPub ***/
SET ECHO ON;

/*** Clean up ***/
DROP TYPE RationalO
/
DROP TYPE Rational
/
DROP PACKAGE RationalP
/
/*** Create rational number type RATIONALO ***/
 
CREATE TYPE RationalO AS OBJECT (
   numerator INTEGER,
   denominator INTEGER,
   MAP MEMBER FUNCTION toReal RETURN REAL,
   MEMBER PROCEDURE normalize,
   STATIC FUNCTION gcd(x INTEGER,
                       y INTEGER) RETURN INTEGER,
   MEMBER FUNCTION plus ( x RationalO) RETURN RationalO
)
/
show errors

CREATE TYPE BODY RationalO AS

  MAP MEMBER FUNCTION toReal RETURN REAL IS
  -- convert rational number to real number
  BEGIN
    RETURN numerator / denominator;
  END toReal;

  MEMBER PROCEDURE normalize IS
   g BINARY_INTEGER;
  BEGIN
   g := RationalO.gcd(numerator, denominator);
   numerator := numerator / g;
   denominator := denominator / g;
  END normalize;

  STATIC FUNCTION gcd(x INTEGER,
                      y INTEGER) RETURN INTEGER IS
  -- find greatest common divisor of x and y
  ans BINARY_INTEGER;
  BEGIN
  IF x < y THEN
     ans := RationalO.gcd(y, x);
  ELSIF (x MOD y = 0) THEN
     ans := y;
  ELSE
     ans := RationalO.gcd(y, x MOD y);
  END IF;
  RETURN ans;
  END gcd;

  MEMBER FUNCTION plus (x RationalO) RETURN RationalO IS
  BEGIN
   return RationalO(numerator * x.denominator + x.numerator * denominator,
                   denominator * x.denominator);
  END plus;
END;
/
show errors

/*** Create rational number type Rational.  No methods this time. ***/
CREATE TYPE Rational AS OBJECT (
   numerator INTEGER,
   denominator INTEGER
)
/
show errors

/*** Create rational number package RATIONALO ***/
CREATE PACKAGE RationalP AS
 FUNCTION toReal(r Rational) RETURN REAL;
 PROCEDURE normalize(r IN OUT Rational);
 FUNCTION gcd(x INTEGER, y INTEGER) RETURN INTEGER;
 FUNCTION plus (r1 Rational, r2 Rational) RETURN Rational;
END rationalP;
/
show errors

CREATE PACKAGE BODY RationalP AS

  FUNCTION toReal(r Rational) RETURN real IS
  -- convert rational number to real number
  BEGIN
    RETURN r.numerator / r.denominator;
  END toReal;

  FUNCTION gcd(x INTEGER, y INTEGER) RETURN INTEGER IS
  -- find greatest common divisor of x and y
  result INTEGER;
  BEGIN
  IF x < y THEN
     result := gcd(y, x);
  ELSIF (x MOD y = 0) THEN
     result := y;
  ELSE
     result := gcd(y, x MOD y);
  END IF;
  RETURN result;
  END gcd;

  PROCEDURE normalize( r IN OUT Rational) IS
   g INTEGER;
   BEGIN
   g := gcd(r.numerator, r.denominator);
   r.numerator := r.numerator / g;
   r.denominator := r.denominator / g;
   END normalize;

  FUNCTION plus (r1 Rational,
                 r2 Rational) RETURN Rational IS
  n INTEGER;
  d INTEGER;
  BEGIN
  n := r1.numerator * r2.denominator + r2.numerator * r1.denominator;
  d := r1.denominator * r2.denominator;
  RETURN Rational(n, d);
  END plus;

END rationalP;
/
show errors

QUIT
