CS
215 - Fundamentals of Programming II
Spring 2008 - Project 1
20
points
Out:
January 23, 2008
Due: January 30, 2008
Reminder: Programming Projects (as opposed to Homework problems) are to be your own work. See syllabus for definitions of acceptable assistance from others.
The instructor's format for class specifications is defined in the on-line handouts An Analysis and Design Style Guideline and An Analysis and Design Style Guideline for Classes. (They are used by the instructor in CS 210.) Links to these handouts also is provided on the CS 215 home page.
Problem Statement
A rational number is a number that can be expressed as an integer or the quotient of an integer divided by a nonzero integer. Expressed as a/b, a is called the numerator and b is called the denominator. Results of the binary arithmetic operations on rational numbers represented by a/b and c/d are as follows:
|
Operator |
Result |
|
a/b + c/d |
(ad + bc) / bd |
|
a/b – c/d |
(ad - bc) / bd |
|
a/b * c/d |
ac / bd |
|
a/b / c/d |
ad / bc, where c not equal to 0 |
In addition, a/b = c/d when ad = bc. From this relationship, the equality and relational operations can be defined.
Consider the following specification for a Rational class that models a rational number. The analysis of each operation is given formally, but the design of each operation is given informally in English.
Specification for Rational Class
|
Objects |
Type |
Name |
|
numerator of the Rational |
int |
numerator |
|
denominator of the Rational |
int |
denominator |
The class invariant is as follows (i.e., all valid objects must meet these conditions):
the denominator must not be 0
the ratio must be in reduced form. For value 0, the denominator is 1; for non-zero rational numbers the greatest common divisor of numerator and denominator is 1. For example, a Rational created with initial values 6/8 will be reduced to 3/4. Note this means that all integer values have denominators of 1.
Explicit-value
constructor - initialize attributes from passed values
Must have
default argument values of 0 and 1 (i.e. value 0)
Precondition:
Initial denominator must be non-zero. Throws RangeError
exception with a suitable error message if not met.
Post
condition: non-zero value numerator and denominator have been
reduced; 0 value denominator is 1
Analysis
|
Objects |
Type |
Kind |
Movement |
Name |
|
initial numerator |
int |
variable |
received |
initialNumerator |
|
initial denominator |
int |
variable |
received |
initialDenominator |
Notes: the greatest common divisor (GCD) of two non-zero integers m and n may be computed using Euclid's recursive algorithm:
if n <= m and n divides m, then GCD(m, n) is n
if n > m, then GCD(m, n) is GCD(n, m)
otherwise GCD(m, n) is GCD(n, the remainder of m divided by n)
GetNumerator - Returns numerator of this Rational
Analysis
|
Objects |
Type |
Kind |
Movement |
Name |
|
numerator of Rational |
int |
variable |
returned |
numerator |
GetDenominator - Returns denominator of this Rational
Analysis
|
Objects |
Type |
Kind |
Movement |
Name |
|
denominator of Rational |
int |
variable |
returned |
denominator |
Reciprocal
- Returns a Rational that is the reciprocal of this Rational.
Precondition:
This Rational must not be value 0. Throws RangeError
exception with a suitable error message in this case
Analysis
|
Objects |
Type |
Kind |
Movement |
Name |
|
Reciprocal Rational |
Rational |
variable |
returned |
----- |
The reciprocal of this Rational is the Rational that produces value 1 when multiplied with this Rational.
LeastCommonDenominator - Returns the least common denominator of this Rational and another Rational
Analysis
|
Objects |
Type |
Kind |
Movement |
Name |
|
another Rational |
Rational |
variable |
received |
aRational |
|
least common denominator |
int |
variable |
returned |
----- |
Notes: The least common denominator is the least common multiple (LCM) of the two denominators. The LCM of two non-zero integers a and b can be computed using the greatest common divisor (GCD) as follows: LCM (a, b) = ab/GCD(a,b).
WriteAsMixedFraction - Write this Rational to an output stream in the form "i+n/d" (no spaces) where i is an integer and n < d. For example, 8/3 would be written as 2+2/3. If n = 0, then write just "i".
Analysis
|
Objects |
Type |
Kind |
Movement |
Name |
|
output stream |
ostream |
variable |
received, passed back |
out |
friend
overloaded arithmetic operator functions: operator+,
operator-,
operator*,
operator/
Returns
a Rational object whose value is the result of performing the
appropriate operation.
operator/
throws RangeError
exception with a suitable error message if the right operand is 0
Analysis
|
Objects |
Type |
Kind |
Movement |
Name |
|
a Rational |
Rational |
variable |
received |
leftOperand |
|
another Rational |
Rational |
variable |
received |
rightOperand |
|
result of computation |
Rational |
variable |
returned |
----- |
friend
overloaded equality and relational operator functions: operator==,
operator!=,
operator<,
operator<=,
operator>,
operator>=
Returns
true if the relationship between the left and right operands is
true, false otherwise
Analysis
|
Objects |
Type |
Kind |
Movement |
Name |
|
a Rational |
Rational |
variable |
received |
leftOperand |
|
another Rational |
Rational |
variable |
received |
rightOperand |
|
result of comparison |
bool |
variable |
returned |
----- |
operator>>
- friend
overloaded operator function that reads Rational values from an
input stream without
prompting
in format "n/d" (no spaces) or just "n" and
store in attributes. Must check that the input denominator is not
0. If so the
Rational object is unchanged
and a RangeError
exception is thrown with a suitable error message.
Post
condition: ratio is reduced for non-zero Rationals, denominator is 1
for value 0.
Analysis
|
Objects |
Type |
Kind |
Movement |
Name |
|
input stream |
istream |
variable |
received, passed back, returned |
in |
|
a Rational |
Rational |
variable |
passed back |
aRational |
Note: the operation in.peek() will return the next character in the input stream without removing it from the stream.
operator<< - friend overloaded operator function that writes Rational to an output stream in format "n/d" (no spaces), except when d = 1, then it just writes "n".
Analysis
|
Objects |
Type |
Kind |
Movement |
Name |
|
output stream |
ostream |
variable |
received, passed back, returned |
out |
|
a Rational |
Rational |
variable |
received |
aRational |
Write the implementation for this Rational class. Note that the function names for this class must be as specified above. The Rational class definition and friend operator function prototypes should be put in header file rational.h with suitable compilation guards. The implementations of the Rational class and friend operator functions should be put in source file rational.cpp.
Write a main program that adequately tests your Rational class in file rationaldriver.cpp. This program should demonstrate that your Rational class meets all of the specifications given above. Part of your grade will depend on how well you test your class. In addition, the submission system will run a specific driver program to test your Rational class.
The
file except.h
with
the RangeError
exception class definition is available on csserver in directory
/home/hwang/cs215/lecture07
and on the course website under January 25. You can copy the file by
changing directories to where you want to put it and typing:
cp /home/hwang/cs215/lecture07/except.h .
(The last '.' indicates the current directory.) You should not modify this file.
You must submit a makefile named Makefile.project1 for your project. Submissions without working makefiles will be assessed up to a 3-point penalty as indicated in the syllabus. It should conform to the examples given in the handout Very Basic make and demonstrated in class.
REMINDER: Your project must compile for it to be graded. Submissions that do not compile will be returned for resubmission and assessed a late penalty. Submissions that do not substantially work also will be returned for resubmission and assessed a late penalty.
Follow the guidelines in the C++ Programming Style Guideline handout. As stated in the syllabus, part of the grade on a programming project depends on how well you adhere to the guidelines. The grader will look at your code listing and grade it according to the guidelines.
Electronically submit a tarfile containing (only) Makefile.project1, rational.h, rational.cpp, and rationaldriver.cpp as explained in the handout Submission Instructions for CS 215. Also hand in hard-copy printouts of these files as explained in the handout. Do not submit except.h, object files, or executable files.
01/22/08