Rational Numbers

Define a class for representating rational numbers, which must be called RationalNum. You may want to use the code for the Fraction class of the previous lab as a starting point for RationalNum.

A rational number can be represented as a quotient of two integers. For example, 1/2, 3/4, and so forth. Represent rational numbers as two values of type int, one for the numerator and one for the denominator. Include a constructor taking two arguments (numerator, denominator), another taking a single argument (numerator) representing whole numbers (numerator/1), and a third taking no arguments, representing zero (0/1). If the constructor that takes two arguments is given a denominator of 0, it should print an error message and return a RationalNum representing (0/1) .

Define a toString method that yields a readable representation of your rational numbers. An acceptable format is: (numerator / denominator). Note that either or both of the numerator and denominator may have a minus sign. If both are negative, the RationalNum should be considered positive, if exactly one is negative, the RationalNum should be considered negative. If the RationalNum is negative, the string format should be (-numerator / denominator). [Note that the negative symbol is part of the numerator.]

Define a private "helper method", private void normalize(), that your methods can invoke to normalize a RationalNum so that if the number is negative, only the numerator is negative (the denominator is always positive), and if both numerator and denominator are negative, then neither remains negative. For example, after normalization (4/-8) would become (-4/8). Any methods that create or modify a RationalNum should invoke normalize.

Define a static method for addition (add) that takes two RationalNum arguments and returns a RationalNum that represents the sum of the two arguments.

Define accessor and mutator methods (int getNumerator(), int getDenominator(), void setNumerator(int newNum), void setDenominator(int newDenom)).

Run your class using the driver class DriverSimple. You may not modify DriverSimple.java. Place a transcript of your program's execution in a lab document.

If the program always prints and represents the rationals in simplest form, I will grant 15% extra credit. (You should be able to use your code from the previous lab.)

Here's a transcript of DriverSimple running with my solution:

Test toString(): r1 should be (1/2) and is (1/2) and r2 should be (8/3) and is (8/3)
The sum of (1/2) and (8/3) should be (19/6) and is (19/6)
r1 should be -5 or (-5/1) and is (-5/1)
r1's top is 5 (should be 5) and bottom is 10 (should be 10)
The sum of (1/2) and (0/1) should be (1/2) and is (1/2)

Part 2: Finishing the implementation

Define static methods for subtraction (sub), division (div) and multiplication (mult), each of which should take two arguments and return a RationalNum representing the result of the numeric operation. For example, Rational.add(num1, num2) should return a RationalNum representing the sum of num1 and num2. Also define a non-static equals method (boolean equals(Rational num)) that returns true if the rational numbers are arithmetically equivalent. Hint: two rational numbers a/b and c/d are equal if a*d = b*c.

Testing Your Class

Test your class using the driver class DriverRationalStatics.java. A trick for testing is to begin by creating a stub (a dummy implementation) for each of the methods that the driver invokes but which you haven't yet implemented. For example, a dummy implementation of the static add method would be (though, of course, you don't need it, because you've already implemented a working version):

public static RationalNum add(RationalNum n1, RationalNum n2) { System.out.println("debug: add() is a stub"); return new RationalNum(0); }

It returns an incorrect value, of course, but at least it can be successfully invoked by the driver and your program will compile. Before finishing the project you'll need to convert all the dummies (stubs) into fully working methods.

Alternatively, you can comment out all the driver code that invokes methods you haven't yet implemented. In that case you'll have to remember to remove the comments eventually. I will test your class against the given DriverRationalStatics.java.

Augmenting Your Class

Add a second, non static, version of each of the operators (add, sub, mult, div) that have a calling object and one argument. The result is given as the changed value of the calling object. For example, if r1.add(r2) is invoked, r1 should be changed to be the sum of the original value of r1 and r2. Note that your class should have two implementations of add, sub, div, and mult (one static and one not). Hint: consider having the non-static versions use their corresponding static versions.

Test your class using the driver class DriverRationalComplete.java.

Place a transcript of the execution of DriverRationalComplete in your lab document.

Submit a zip file containing RationalNum.java and your lab document, to the dropbox. If you did not complete the assignment, please indicate this with a comment at the top of your lab document.

Acknowledgement: (This is a modified version of Programming Project #6 from Robert Savitch's Absolute Java).