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
- ExtendedNumber.java (generic interface)
- TestRational.java (testing driver program)
- Rational.java (the class you are creating)
Requirements
Here are your class requirements:
- Remember to include documentation comments
- There is a starting document available for the rational class which includes
some of the steps listed below. Start with the starting document.
- Name your class: Rational
- It must implement both the ExtendedNumber<Rational> and Comparable<Rational> interfaces
- It must contain a public enum named DisplayStyle with
the following two values: FRACTIONAL, FLOATING_POINT
- It must contain two private instance variables. They should both be
of type int. They should store the numerator and denominator.
- It must contain a private static variable named displayStyle to store one of
the enum values. It should be initialized to the value: FRACTIONAL.
- 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.
- 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:
- If the denominator is 0, throw an IllegalArgumentException with the message,
"Invalid rational number: n/d", where the n and d are replaced with the
requested numerator and denominator.
- If the numerator is zero, set the denominator to one.
- If the denominator is negative, change the sign of both the numerator and denominator.
- Call the simplify method to reduce the rational number to its simplest form.
- 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.
- 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.
- It must contain a public static method with the signature: void setDisplayStyle(DisplayStyle).
This method should set the appropriate static variable within the class.
- 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).
- 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)
- 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)
- 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)
- 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)
- 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.
- 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.
- It must include overrides for the following public methods:
- 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.
- boolean equals(Object)
- int hashCode()
- 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