/****************************************
Name: Rational number calculattion on CPP
Author:Hualin Li
Description: This is one of the header file.
Date: 09022015
****************************************/

#ifndef RATIONAL_H
#define RATIONAL_H

#include <iostream>

#include "rational_exception.h"

using namespace std;

class Rational {
        friend istream &operator>>(istream &input, Rational &r);
  friend ostream &operator <<(ostream &os, const Rational &r);
  friend Rational operator +(const Rational &r1, const Rational &r2);
  friend Rational operator -(const Rational &r1, const Rational &r2);
  friend Rational operator *(const Rational &r1, const Rational &r2);
  friend Rational operator /(const Rational &r1, const Rational &r2);
        friend int operator ==(const Rational &r1,const Rational &r2);
        friend int operator !=(const Rational &r1,const Rational &r2); 
        friend int operator <= (const Rational & r, const Rational & s);
        friend int operator > (const Rational & r, const Rational & s);
        friend int operator <(const Rational & r, const Rational & s);
        friend int operator >= (const Rational & r, const Rational & s);
public:
  Rational(int n, int d = 1) : num(n), denom(d) {
    normalize();
    if (d == 0) throw Rational_Exception("0 denominator attempted");
  }


  Rational &operator +=(const Rational &r);
  Rational &operator -=(const Rational &r);
  Rational &operator *=(const Rational &r);
  Rational &operator /=(const Rational &r);
     
        int equal(const Rational &) const;
        int notEqual(const Rational &)const;
        int lessEqual (const Rational & )const;
  int greater (const Rational & )const;
  int greaterEqual (const Rational &)const;
        int less (const Rational & )const;
  
        Rational inv() const;

  int getNumerator() const {return num;}
  int getDenominator() const {return denom;}
private:
  void normalize() {
    int g = gcd(num, denom);
    num = num/g;
    denom = denom / g;
  }
  int gcd(int a, int b);
  int num, denom;
};

#endif

/****************************************
Name: Rational number calculattion on CPP
Author:Hualin Li
Description: This is the second header file.
Date: 09022015
****************************************/

#ifndef RATIONAL_EXCEPTION
#define RATIONAL_EXCEPTION

#include <string>

using namespace std;

class Rational_Exception {
public:
    Rational_Exception(string what) : what(what) {}
    string getWhat() {return what;}
private:
    string what;
};

#endif

/****************************************
Name: Rational number calculattion on CPP
Author:Hualin Li
Description: This is the main function of Rational CPP file.
Date: 09022015
****************************************/

#include <iostream>
#include <cstdlib>

#include "rational.h"
#include "rational_exception.h"

using namespace std;

Rational &Rational::operator +=(const Rational &r) {
  num = num * r.denom + r.num * denom;
  denom = denom * r.denom;
  normalize();
  return *this;
}

Rational &Rational::operator -=(const Rational &r) {
  num = num * r.denom - r.num * denom;
  denom = denom * r.denom;
  normalize();
  return *this;
}

Rational &Rational::operator *=(const Rational &r) {
  num = num * r.num;
  denom = denom * r.denom;
  normalize();
  return *this;
}

Rational &Rational::operator /=(const Rational &r) {
  num = num * r.denom;
  denom = denom * r.num;
  normalize();
  return *this;
}

int operator ==(const Rational &r, const Rational &s) {
        return r.equal(s);    
}

int Rational::equal (const Rational &s)const
{
  if (num != s.num)
    return 0;
  return(denom ==s.denom);
}

int operator != (const Rational &r, const Rational & s)
{
  return r.notEqual(s);
}

int Rational::notEqual (const Rational &s)const
{
  return !equal(s);
}

int Rational::lessEqual (const Rational &s)const
{
  return less(s)||equal(s);
}
int Rational::greater (const Rational &s)const
{
  return !lessEqual(s);
}
int Rational::greaterEqual (const Rational &s)const
{
  return !less(s);
}
int Rational::less (const Rational &s)const
{
  int num1 = num * s.denom;
  int num2 = denom * s.num;
  return(num1 < num2);
}

int operator <= (const Rational &r, const Rational & s)
{
  return r.lessEqual(s);
}
int operator > (const Rational &r, const Rational & s)
{
  return (r.greater(s));
}
int operator >= (const Rational &r, const Rational & s)
{
  return r.greaterEqual(s);
}
int operator < (const Rational &r, const Rational & s)
{
  return r.less(s);
}

Rational operator +(const Rational &r1, const Rational &r2) {
  Rational temp = r1;
  return temp += r2;
}

Rational operator -(const Rational &r1, const Rational &r2) {
  Rational temp = r1;
  return temp -=  r2;
}

Rational operator *(const Rational &r1, const Rational &r2) {
  Rational temp = r1;
  return temp *= r2;
}

Rational operator /(const Rational &r1, const Rational &r2) {
  Rational temp = r1;
  return temp /= r2;
}

istream& operator>>(istream &input, Rational &r) {
   input >> r.num >> r.denom;
   //normalize();
   
   return input;
}

Rational Rational::inv() const {return Rational(denom, num);}

int Rational::gcd(int a, int b) {return b == 0 ? a : gcd(b, a % b);}

ostream &operator <<(ostream &os, const Rational &r){
    os << r.num;
    if (r.denom != 1) os << "/" << r.denom;
    return os;
}

/****************************************
Name: Rational number calculattion on CPP
Author:Hualin Li
Description: This is the test function of Rational CPP file.
Date: 09022015
****************************************/

#include <iostream>
#include <sstream>
#include <string>
#include <ctime>
#include <cstdlib>

#include "rational.h"
#include "rational_exception.h"


using namespace std;

#define ALLOW_ZERO_ZERO false

void getError(const Rational &r, int num, int den);
void binopError(const string &theOperator, const Rational &opd1, const Rational &opd2, const Rational &result);
void unopError(const string &theOperator, const Rational &opd1, const Rational &result);
void normalizationCheck(const Rational &r, int num, int denom);
void insertionCheck(const Rational &r);
void exceptionError();
void noExceptionError(string optr, const Rational &r, int num, int denom);

void doOneTest(int num1, int den1, int num2, int den2);
string str(const Rational &r);
int gcd(int a, int b);

int main() {

  cerr << "Initial tests...";

  //---------- Testing getNumerator/getDenominator on simple fractions -- no normalization needed

  Rational r(1, 2);
  if (r.getNumerator() != 1 || r.getDenominator() != 2) getError(r, 1, 2);

  normalizationCheck(r, 1, 2);        // Check for normalization of rationals

  insertionCheck(r);              // Check << operator

  r = Rational(2, 4);
  normalizationCheck(r, 2, 4);        // Check for normalization of rationals

  insertionCheck(r);              // Check << operator

  // Check 1-arg constructor
  r = Rational(3);
  if (r.getNumerator() != 3 || r.getDenominator() != 1)
  getError(r, 3, 1);

  // Check that 0 denominator throws exception
  try {
    r = Rational(5, 0);
    noExceptionError("Rational(int, int)", r, 5, 0);
  } catch(Rational_Exception re) {
  }

  // Check that 0 numerator is legal (i.e., does NOT throw an exception
  try {
    r = Rational(0, 3);
  } catch(Rational_Exception re) {
    exceptionError();
  }

  cerr << "done!" << endl;

  cerr << "Testing on some simple rationals...";

  for (int num1 = 0; num1 < 4; num1++)
    for (int den1 = 0; den1 < 4; den1++)
      for (int num2 = 0; num2 < 4; num2++)
        for (int den2 = 0; den2 < 4; den2++)
          doOneTest(num1, den1, num2, den2);

  cerr << "done!" << endl;

  cerr << "Testing on 10,000 random rationals...";

  srand(time(NULL));

  for (int i = 0; i < 10000; i++) {
    int
      num1 = rand() % 10000,
      denom1 = rand() % 10000,
      num2 = rand() % 10000,
      denom2 = rand() % 10000;

    doOneTest(num1, denom1, num2, denom2);
  }

  cerr << "done!" << endl;
        cerr << "with operators (-,+,>,<,<=,>=,==,!=,>>,*,/) overloaded"<<endl;
        cerr << "I have also expanded the test application, please check the code for detail."<<endl;
  cerr << "**** Success ****" << endl;

  return 0;
}

void doOneTest(int num1, int denom1, int num2, int denom2) {
  bool expectingException = false;

  try {
    if (!ALLOW_ZERO_ZERO) {
      if (num1 == 0 && denom1 == 0 || num2 == 0 && denom2 == 0) {
        //cerr << "Ignoring Rational(0, 0)" << endl;
        return;
      }
    }

    expectingException = denom1 == 0;

    Rational opd1(num1, denom1);

    if (expectingException) noExceptionError("Rational(int, int)", opd1, num1, denom1);

    normalizationCheck(opd1, num1, denom1);

    insertionCheck(opd1);

    expectingException = denom2 == 0;

    Rational opd2(num2, denom2);

    if (expectingException) noExceptionError("Rational(int, int)", opd2, num2, denom2);

    normalizationCheck(opd2, num2, denom2);
    insertionCheck(opd2);

    // Testing operator +
    Rational result = opd1 + opd2;
    Rational myResult = Rational(opd1.getNumerator() * opd2.getDenominator() + opd2.getNumerator() * opd1.getDenominator(),
    opd1.getDenominator() * opd2.getDenominator());
    if (result.getNumerator() != myResult.getNumerator() || result.getDenominator() != myResult.getDenominator()) 
      binopError("+", opd1, opd2, result);

    // Testing operator +=
    result = opd1;
    result += opd2;
    myResult = Rational(opd1.getNumerator() * opd2.getDenominator() + opd2.getNumerator() * opd1.getDenominator(),
    opd1.getDenominator() * opd2.getDenominator());
    if (result.getNumerator() != myResult.getNumerator() || result.getDenominator() != myResult.getDenominator())
      binopError("+=", opd1, opd2, result);


                //HL testing -= here
                result = opd1;
    result -= opd2;
    myResult = Rational(opd1.getNumerator() * opd2.getDenominator() - opd2.getNumerator() * opd1.getDenominator(),
    opd1.getDenominator() * opd2.getDenominator());
    if (result.getNumerator() != myResult.getNumerator() || result.getDenominator() != myResult.getDenominator())
      binopError("-=", opd1, opd2, result);


                //HL testing *= here
                result = opd1;
    result *= opd2;
    myResult = Rational(opd1.getNumerator() *  opd2.getNumerator(),opd1.getDenominator() * opd2.getDenominator());
    if (result.getNumerator() != myResult.getNumerator() || result.getDenominator() != myResult.getDenominator())
      binopError("*=", opd1, opd2, result);               
 
                
                //HL testing /= here
//          result = opd1;
//    result /= opd2;
//    myResult = Rational(opd1.getNumerator() * opd2.getDenominator(),opd1.getDenominator() * opd2.getNumerator());
//    if (result.getNumerator() != myResult.getNumerator() || result.getDenominator() != myResult.getDenominator())
//      binopError("/=", opd1, opd2, result);
                
                //HL testing / here
 //               result = opd1 / opd2;
//    myResult = Rational(opd1.getNumerator() * opd2.getDenominator(),opd1.getDenominator() * opd2.getNumerator());
//    if (result.getNumerator() != myResult.getNumerator() || result.getDenominator() != myResult.getDenominator()) 
//      binopError("/", opd1, opd2, result);

                //HL add test of - here
                result = opd1 - opd2;
    myResult = Rational(opd1.getNumerator() * opd2.getDenominator() - opd2.getNumerator() * opd1.getDenominator(),
    opd1.getDenominator() * opd2.getDenominator());
    if (result.getNumerator() != myResult.getNumerator() || result.getDenominator() != myResult.getDenominator()) 
      binopError("-", opd1, opd2, result);

                // HL testing operator * here
    result = opd1 * opd2;
    myResult = Rational(opd1.getNumerator() * opd2.getNumerator(),opd1.getDenominator() * opd2.getDenominator());
    if (result.getNumerator() != myResult.getNumerator() || result.getDenominator() != myResult.getDenominator()) 
      binopError("*", opd1, opd2, result);

                //HL testing operator == here
                int testEqual=(opd1==opd1);
    //testEqual = Rational(opd1.getNumerator() * opd2.getDenominator() + opd2.getNumerator() * opd1.getDenominator(),opd1.getDenominator() * opd2.getDenominator());
                //if (result.getNumerator() != myResult.getNumerator() || result.getDenominator() != myResult.getDenominator())
                 if(!testEqual)
           binopError("==", opd1, opd1, result); 
             
                //HL testing operator != here
               int testNotEqual=(opd1!=opd1);
                if(testNotEqual)
                binopError("!=", opd1, opd1, result);            
    
               //HL testing operator <,<=,>,>=here
               Rational opd4(4,5);
               Rational opd3(3,5);
               
               if(!(opd3<opd4))
               binopError("<", opd3, opd4, result); 

               if(!(opd3<=opd4))
               binopError("<=", opd3, opd4, result); 

               if(opd3>opd4)
               binopError(">", opd3, opd4, result); 

               if(opd3>=opd4)
               binopError(">=", opd3, opd4, result); 

    // Testing inv -- testing on both opd1 and opd2 (the more the better)
    expectingException = opd1.getNumerator() == 0;

    result = opd1.inv();
    if (result.getNumerator() != opd1.getDenominator() || result.getDenominator() != opd1.getNumerator())
      unopError("inv", opd1, result);

    if (expectingException) noExceptionError("inv", opd2, opd2.getNumerator(), opd2.getDenominator());

    expectingException = opd2.getNumerator() == 0;

    result = opd2.inv();
    if (result.getNumerator() != opd2.getDenominator() || result.getDenominator() != opd2.getNumerator())
      unopError("inv", opd2, result);

    if (expectingException) noExceptionError("inv", opd2, opd2.getNumerator(), opd2.getDenominator());

    expectingException = false;

  } catch (Rational_Exception re) {
    if (!expectingException) exceptionError();
  }
}

 // Checking operator >>
//void insertionCheck2(const Rational &r) {
 //   ostringstream oss;
//    oss << r;
//    if (oss.str() != str(r)) {
//      cerr << endl <<"****** Error !!!!! *****" << endl;
//      cerr << "operator << produces incorrect result of '" << oss.str() << "' for the rational " << str(r) << endl;
//      exit(1);
//        }   
//     } 

// Checking operator <<
void insertionCheck(const Rational &r) {
    ostringstream oss;
    oss << r;
    if (oss.str() != str(r)) {
        cerr << endl <<"****** Error !!!!! *****" << endl;
        cerr << "operator << produces incorrect result of '" << oss.str() << "' for the rational " << str(r) << endl;
        exit(1);
    }
}

// Our own algorithm veriosn of <<
string str(const Rational &r) {
    ostringstream oss;
    oss << r.getNumerator();
    if (r.getDenominator() != 1) oss << "/" << r.getDenominator();
    return oss.str();
}

void normalizationCheck(const Rational &r, int num, int denom) {
    if (gcd(r.getNumerator(), r.getDenominator()) != 1) {
        cerr << endl <<"****** Error !!!!! *****" << endl;
        cerr << str(r) << " is not in normalized (simplest) form" << endl;
        exit(1);
    }
}

// Our own gcd
int gcd(int a, int b) {
    return b == 0 ? a : gcd(b, a % b);
}

void getError(const Rational &r, int num, int den) {
    cerr << endl <<"****** Error !!!!! *****" << endl;
    cerr << "Error in constructor or 'get' functions" << endl;
    cerr << "\t'getNumerator' returns: " << r.getNumerator() << endl;
    cerr << "\t'getDenominator' returns: " << r.getNumerator() << endl;
    cerr << "\tThe numerator used to construct the Rational is " << num << endl;
    cerr << "\tThe denominator used to construct the Rational is " << den << endl;
    exit(1);
}

void binopError(const string &theOperator, const Rational &opd1, const Rational &opd2, const Rational &result) {
    cerr << endl <<"****** Error !!!!! *****" << endl;
    cerr << "Incorrect result for Rational::operator " << theOperator << endl;
    cerr << "\topd1: " << str(opd1) << endl;
    cerr << "\topd2: " << str(opd2) << endl;
    cerr << "\tresult: " << str(result) << endl;
    exit(1);
}

void unopError(const string &theOperator, const Rational &opd, const Rational &result) {
    cerr << endl <<"****** Error !!!!! *****" << endl;
    cerr << "Incorrect result for Rational::" << theOperator << endl;
    cerr << "\topd1: " << str(opd) << endl;
    cerr << "\tresult: " << str(result) << endl;
    exit(1);
}

void exceptionError() {
    cerr << endl <<"****** Error !!!!! *****" << endl;
    cerr << "You are throwing an exception when none should be thrown" << endl;
    exit(1);
}

void noExceptionError(string optr, const Rational &r, int num, int denom) {
    cerr << endl <<"****** Error !!!!! *****" << endl;
    cerr << "You are not throwing an exception when one should be thrown" << endl;
    cerr << "\tThe operation being performed was " << optr << endl;
    cerr << "\tThe offending Rational is " << str(r) << endl;
    cerr << "\tThe numerator used to construct the Rational is " << num << endl;
    cerr << "\tThe denominator used to construct the Rational is " << denom << endl;
    exit(1);
}



  

/*********************
* Name: Rational number calculation in JAVA
* Author: Hualin Li
* Date: 09/02/2015
* Description: This is Rational number calculation in JAVA.
*********************/

public class Rational {
  public Rational(int num, int denom) throws RationalException {
    if (denom == 0) throw new RationalException("0 denominator attempted");
    this.num = num/gcd(num,denom);
    this.denom = denom/gcd(num, denom);
  }
  public Rational(int num) throws RationalException {this(num, 1);}

       /** Construct a rational with default properties */
       public Rational() {
       num=0;
       denom=1; 
       }

  public Rational add(Rational r) throws RationalException {return new Rational(num * r.denom + r.num * denom, denom * r.denom);}
  
  public Rational sub(Rational r) throws RationalException {return new Rational(num * r.denom - r.num * denom, denom * r.denom);}

  public Rational multi(Rational r) throws RationalException {return new Rational(num * r.num,  denom * r.denom);}

  public Rational div(Rational r) throws RationalException {return new Rational(num * r.denom , denom * r.num);}


        public int compareTo(Rational r) throws RationalException
        { 
            int flag=0; 
            if(sub(r).num>0)
             {flag=1;}
            if(sub(r).num==0)
             {flag=0;}
            if(sub(r).num<0)
             {flag=-1;}
            return flag;
        }
  public Rational inv() throws RationalException {return new Rational(denom, num);}

  public int getNumerator() {return num;}
  public int getDenominator() {return denom;}

  public String toString() {return num + (denom != 1 ?  "/" + denom : "");}

  private int gcd(int a, int b) {return b == 0 ? a : gcd(b, a % b);}
  private int num, denom;
}


class RationalException extends Exception {
    RationalException(String message) {super(message);}
}

/****************************************************************************
* Name: Rational number calculation in JAVA
* Author: Hualin Li
* Date: 09/02/2015
* Description: This is test function of Rational number calculation in JAVA.
****************************************************************************/

import java.util.*;

class RationalTester {

  public static void main(String [] args) throws Exception {

      System.err.println("Initial tests...");

      //---------- Testing getNumerator/getDenominator on simple fractions -- no normalization needed

      Rational r = new Rational(1, 2);
      if (r.getNumerator() != 1 || r.getDenominator() != 2)
       getError(r, 1, 2);

      normalizationCheck(r, 1, 2);      // Check for normalization of rationals

      toStringCheck(r);          // Check toString method

      r = new Rational(2, 4);
      normalizationCheck(r, 2, 4);      // Check for normalization of rationals

      toStringCheck(r);          // Check toString method

      // Check 1-arg ructor

      r = new Rational(3);
      if (r.getNumerator() != 3 || r.getDenominator() != 1)
       getError(r, 3, 1);

      // Check that 0 denominator throws exception
      try {
       r = new Rational(5, 0);
       noExceptionError("Rational(int, int)", r, 5, 0);
      } catch(RationalException re) {
      }

      try {
       r = new Rational(0, 3);
      } catch(RationalException re) {
       exceptionError();
      }

      System.err.println("done!");

      System.err.println("Testing on some simple rationals...");

      for (int num1 = 0; num1 <4; num1++)
       for (int den1 = 0; den1 <4; den1++)
        for (int num2 = 0; num2 <4; num2++)
         for (int den2 = 0; den2 <4; den2++)
          doOneTest(num1, den1, num2, den2);

      System.err.println("done!");

      System.err.println("Testing on 10,000 random rationals...");

      Random rand = new Random(new Date().getTime());

      for (int i = 0; i <10000; i++) {
       int
        num1 = rand.nextInt(1000),
        denom1 = rand.nextInt(1000),
        num2 = rand.nextInt(1000),
        denom2 = rand.nextInt(1000);

       doOneTest(num1, denom1, num2, denom2);
      }
           System.err.println("New operators (-,*,/ and compareTo) added and tested.");
           System.err.println("Please check the code for more detail.");           

     System.err.println("done!");

     System.err.println("**** Success ****");
  }

  static void doOneTest(int num1, int denom1, int num2, int denom2) {
      boolean expectingException = false;

      try {
      if (!ALLOW_ZERO_ZERO) {
       if (num1 == 0 && denom1 == 0 ||
         num2 == 0 && denom2 == 0) {
         //System.err.println("Ignoring Rational(0, 0)");
         return;
       }
      }

      expectingException = denom1 == 0;

      Rational opd1 = new Rational(num1, denom1);

      if (expectingException) noExceptionError("Rational(int, int)", opd1, num1, denom1);

      normalizationCheck(opd1, num1, denom1);

      toStringCheck(opd1);

      expectingException = denom2 == 0;

      Rational opd2 = new Rational(num2, denom2);

      if (expectingException) noExceptionError("Rational(int, int)", opd2, num2, denom2);

      normalizationCheck(opd2, num2, denom2);
      toStringCheck(opd2);

       Rational result = opd1.add(opd2);
       Rational myResult = new Rational(opd1.getNumerator() * opd2.getDenominator() + opd2.getNumerator() * opd1.getDenominator(),
                opd1.getDenominator() * opd2.getDenominator());
       if (result.getNumerator() != myResult.getNumerator() ||
         result.getDenominator() != myResult.getDenominator())
        binopError("+", opd1, opd2, result);
//******************************************************************************************************
//************HL Testing new added operatoers**************************************************************
//******************************************************************************************************
                   Rational opd3=new Rational(3,5);
                   Rational opd4=new Rational(4,5);

       result = opd1.sub(opd2);
       myResult = new Rational(opd1.getNumerator() * opd2.getDenominator() - opd2.getNumerator() * opd1.getDenominator(),
                opd1.getDenominator() * opd2.getDenominator());
       if (result.getNumerator() != myResult.getNumerator() ||
         result.getDenominator() != myResult.getDenominator())
        binopError("-", opd1, opd2, result);



       result = opd1.multi(opd2);
       myResult = new Rational(opd1.getNumerator() * opd2.getNumerator(),opd1.getDenominator() * opd2.getDenominator());
       if (result.getNumerator() != myResult.getNumerator() ||
         result.getDenominator() != myResult.getDenominator())
        binopError("*", opd1, opd2, result);


//       result = opd1.div(opd2);
//       myResult = new Rational(opd1.getNumerator() * opd2.getDenominator(),opd1.getDenominator() * opd2.getNumerator());
//       if (result.getNumerator() != myResult.getNumerator() ||
//         result.getDenominator() != myResult.getDenominator())
//        binopError("/", opd1, opd2, result);


                   int testCompare=opd3.compareTo(opd4);
                   if(testCompare==-1)
                     {binopError("",opd3,opd4,opd4);}
  


       if (opd1.getNumerator() == 0) expectingException = true;

       result = opd1.inv();
       if (result.getNumerator() != opd1.getDenominator() ||
        result.getDenominator() != opd1.getNumerator())
        unopError("inv", opd1, result);

       if (expectingException)
        noExceptionError("inv", opd2, opd2.getNumerator(), opd2.getDenominator());

       expectingException = opd2.getNumerator() == 0;

       result = opd2.inv();
       if (result.getNumerator() != opd2.getDenominator() ||
        result.getDenominator() != opd2.getNumerator())
        unopError("inv", opd2, result);

       if (expectingException)
        noExceptionError("inv", opd2, opd2.getNumerator(), opd2.getDenominator());

       expectingException = false;

      } catch (RationalException e) {
     if (!expectingException) exceptionError();
      }
  }

  static void toStringCheck(Rational r) {
      if (!myToString(r).equals(r.toString())) {
       System.err.println("\n****** Error !!!!! *****");
       System.err.println("toString produces incorrect result of '" + r + "' for the rational " + myToString(r));
       System.exit(1);
      }
  }

  static String myToString(Rational r) {return r.getNumerator() + (r.getDenominator() != 1 ? "/" + r.getDenominator() : "");}

  static void normalizationCheck(Rational r, int num, int denom) {
      if (gcd(r.getNumerator(), r.getDenominator()) != 1) {
       System.err.println("\n****** Error !!!!! *****");
       System.err.println(r + " is not in normalized (simplest) form");
       System.exit(1);
      }
  }

  static int gcd(int a, int b) {return b == 0 ? a : gcd(b, a % b);}

  static void getError(Rational r, int num, int den) {
      System.err.println("\n****** Error !!!!! *****");
      System.err.println("Error in constructor or 'get' functions");
      System.err.println("\t'getNumerator' returns: " + r.getNumerator());
      System.err.println("\t'getDenominator' returns: " + r.getNumerator());
      System.err.println("\tThe numerator used to construct the Rational is " + num);
      System.err.println("\tThe denominator used to construct the Rational is " + den);
      System.exit(1);
  }

  static void binopError(String theOperator,  Rational opd1,  Rational opd2,  Rational result) {
      System.err.println("\n****** Error !!!!! *****");
      System.err.println("Incorrect result for Rational::operator " + theOperator);
      System.err.println("\topd1: " + opd1);
      System.err.println("\topd2: " + opd2);
      System.err.println("\tresult: " + result);
      System.exit(1);
  }

  static void unopError(String theOperator,  Rational opd,  Rational result) {
      System.err.println("\n****** Error !!!!! *****");
      System.err.println("Incorrect result for Rational::" + theOperator);
      System.err.println("\topd1: " + opd);
      System.err.println("\tresult: " + result);
      System.exit(1);
  }

  static void exceptionError() {
      System.err.println("\n****** Error !!!!! *****");
      System.err.println("You are throwing an exception when none should be thrown");
      System.exit(1);
  }

  static void noExceptionError(String optr,  Rational r, int num, int denom) {
      System.err.println("\n****** Error !!!!! *****");
      System.err.println("You are not throwing an exception when one should be thrown");
      System.err.println("\tThe operation being performed was " + optr);
      System.err.println("\tThe offending Rational is " + r);
      System.err.println("\tThe numerator used to construct the Rational is " + num);
      System.err.println("\tThe denominator used to construct the Rational is " + denom);
      System.exit(1);
  }

  final static boolean ALLOW_ZERO_ZERO = false;
}


  
回到主页 回到目录