For this assignment, create a C++ class rational that implements rational numbers (fractions) and operations on them. You should also write a main program to test your rational class, or use the one we provide.
The main goal of this assignment is to gain experience creating a C++ class, to learn how to create a user-defined type, to experiment with operator overloading, and to learn how to create appropriate header and implementation files for new classes.
The rest of this handout contains a description of the operations to be included in the rational class and some implementation hints and suggestions.
A rational number p/q can be represented as pair of integers p and q. Arithmetic on rationals follows the usual rules: p/q+r/s = (ps+qr)/qs, and so forth.
The only subtle point is that there are many possible representations for each rational. For example, 1/2 = -3/-6 = 1024/2048 = .... This can cause difficulties when, for example, comparing two rationals for equality. For simplicity, you should store rationals in lowest terms, i.e., the numerator and denominator should have no common factors. Dividing out common factors also reduces the chances of generating a numerator or denominator that is too large to be stored in a C++ int variable. It is also a good idea not to have two representations of the same rational with opposite signs --- there are fewer cases to deal with if we don't allow both (-3)/4 and 3/(-4) to be used as representations of -(3/4).
To avoid these problems, your implementation of rationals must obey the following invariant: as far as a client of the rational class can tell, all rationals have the form p/q, with q>0, and with p and q having no common factors other than +1 or -1. While you are not specifically forbidden from creating rational numbers that have common factors in the numerator and denominator or that have a negative denominator, you will find it easiest to always simplify rational numbers to avoid this. In any case, a client of your rational class should never be able to observe numerators or denominators that violate these rules.
Given an arbitrary numerator x and denominator y, the rational number p/q representing x/y can be computed as follows:
The greatest common divisor of two numbers x and y can be computed by several methods; here is one (feel free to use this code into your program).
#include <stdlib.h> // library containing abs( ) // = greatest common divisor of non-zero integers x and y. int gcd (int x, int y) { x = abs(x); y = abs(y); while (x != y) if (x > y) x = x - y; else // x > y y = y - x; return x; }
For this assignment you can ignore the possibility of a denominator being 0. An industrial-strength rational package would have to do something sensible in that case.
You should implement a C++ class rational with the following operations.
Constructors | rational(), rational(int,int), rational(int) |
Access functions | num (numerator), denom (denominator) |
Operations | unary - and binary + - * / |
Relations | <, <=, ==, !=, >=, > |
Stream output | << |
The binary constructor rational (int, int) should create the rational p/q given p and q as arguments.. The unary constructor rational(int) should create the rational k/1 given an integer value k as an argument. The null constructor rational() should create some legal rational: 0/1 is suggested. The stream output operator << should write a rational p/q by writing the integer p, followed by a slash character ('/') followed by the integer q. No spaces should be written as part of a rational value.
The interface to the class should be placed in a file rational.h and the implementation should be in a separate file rational.cpp. Be careful to hide any additional functions and data used in the implementation so these are not visible in other files.
You also need to create a simple test program (one which contains a main() function) in a different file to demonstrate that your rational package works properly. It should read successive groups of four integers p, q, r, and s and print the results of p/q+r/s, p/q-r/s, -(p/q), p/q < r/s, etc. You may find the complex number class and test program presented in lecture to be a useful model. We have provided a sample test program that you can use, although you may find it more instructive to write your own. If you do write your own, it should provide test output that matches the sample program (i.e., operations tested and results printed in the same order). This will greatly help us check your work.
Hint: You may be able to simplify the implementation by taking advantage of facts like this: If r and s are rationals and == has been implemented for rationals, then r!=s can be implemented easily as !(r==s).
Note that this quarter you will need to create your own projects and workspaces for the compiler. You can read how on the tips page. Those working in the IPL will want to check the tips for MSVC 6.0 and create a Win32 Console Application.
Your program should conform to the course style guide , which is also included in the course packet.
When you have finished, go back to the main homework 1 page and follow the directions for turning in your homework.