CIS 260 Rational number assignment

The objective of this assignment is to write a class that handles rational numbers and conforms to an API contract supplied by a generic class. Rational numbers are numbers which can be represented as fractions which have an integer numerator and denominator, where the denominator is not allowed to be 0. The generic, abstract base class and a test class (which is unfortunately not thorough) is provided.

Resources

  1. ExtendedNumber.java (generic interface)
  2. TestRational.java (testing driver program)
  3. Rational.java (the class you are creating)

Requirements

Here are your class requirements:

  1. Remember to include documentation comments
  2. There is a starting document available for the rational class which includes some of the steps listed below. Start with the starting document.
  3. Name your class: Rational
  4. It must implement both the ExtendedNumber<Rational> and Comparable<Rational> interfaces
  5. It must contain a public enum named DisplayStyle with the following two values: FRACTIONAL, FLOATING_POINT
  6. It must contain two private instance variables. They should both be of type int. They should store the numerator and denominator.
  7. It must contain a private static variable named displayStyle to store one of the enum values. It should be initialized to the value: FRACTIONAL.
  8. It should include three public constructors: a default constructor which sets the numerator and denominator to 1, a copy constructor, and a constructor that accepts int values for both the numerator and denominator. The constructors must do all error checking and simplification described for the setNums(int, int) and simplify() methods.
  9. It must contain a private instance method with the signature: void setNums(int, int). The two parameters are the requested numerator and denominator. Do the following:
  10. It must contain a private instance method named simplify(). All it has to do is divide the numerator and denominator by their greatest common denominator.
  11. It must contain a static method with the signature: int gcd(int, int). It should return the greatest common divisor of its two parameters. The details of a recursive version are included later on this page.
  12. It must contain a public static method with the signature: void setDisplayStyle(DisplayStyle). This method should set the appropriate static variable within the class.
  13. It must implement public add, subtract, multiply and divide methods. Details of the math are included below. Don't forget that the results must be simplified (which should be automatic if you are creating a new Rational object).
  14. Addition should return a new Rational object with the appropriate numerator and denominator. Addition is defined as follows: a/b + c/d ==> (a*d + c*b)/(b*d)
  15. Subtraction should return a new Rational object with the appropriate numerator and denominator. Subtraction is defined as follows: a/b - c/d ==> (a*d - c*b)/(b*d)
  16. Multiplication should return a new Rational object with the appropriate numerator and denominator. Multiplication is defined as follows: a/b * c/d ==> (a*c)/(b*d)
  17. Division should return a new Rational object with the appropriate numerator and denominator. Division is defined as follows: a/b / c/d ==> (a*d)/(c*b)
  18. It should be noted that we have ignored what happens with division when the second Rational number is 0. In a full implementation, we would expect to throw a runtime exception.
  19. It must implement the public increment and decrement methods. Increment is just adding the denominator to the numerator. Decrement is just subtracting the denominator from the numerator. Both methods return the current object.
  20. It must include overrides for the following public methods:
    1. int compareTo(Rational): return 0 if the argument has the same value as the current Rational, -1 if the current object is less than the argument, and 1 if the current object is greater than the argument.
    2. boolean equals(Object)
    3. int hashCode()
    4. String toString(): Stringify the Rational number as either a fraction or a floating-point number depending on the value of the static variable holding the DisplayStyle value.

GCD method

    private static int gcd(final int a, final int b) {
        int x = a, y = b;
        if (x < y) x = -x;
        if (y > 0) y = -y;
        if (y == 0) return x;
        return gcd(y, x%y);
    }

Extra credit opportunity

This assignment needs a really good test driver to test out all the features of the Rational class and try to break it. I am willing to provide up to five points of extra credit for such a test driver so I can include it the next time I use this assignment.

Sample output

r[0] = 1/1
r[1] = 2/3
r[2] = 4/5
r[3] = 5/4
r[4] = 4/3
r[5] = 3/2
Testing methods:
r[1].add(r[4]) = 2/1
r[1].subtract(r[4]) = -2/3
r[1].divide(r[4]) = 1/2
r[1].multiply(r[4]) = 8/9
r[1].multiply(r[5]) = 1/1
r[1].increment() = 5/3
r[1].decrement() = 2/3
Testing equality and comparison methods:
r[2] set to r[0]
r[0].compareTo(r[1]) = 1
r[0].compareTo(r[2]) = 0
r[0].compareTo(r[3]) = -1
r[0].equals(r[1]) = false
r[0].equals(r[2]) = true
r[0].equals(r[3]) = false
Testing display style setting:
r[0] = 1/1 = 1.0
r[1] = 2/3 = 0.6666666666666666
r[2] = 1/1 = 1.0
r[3] = 5/4 = 1.25
r[4] = 4/3 = 1.3333333333333333
r[5] = 3/2 = 1.5
Try to create illegal Rational object:
Error: Invalid rational number: 2/0
*** End of test