/* Define a class for rational numbers. A rational number is a number that can be represented as the quotient of two integers. For example, 1/2, 3/4, 64/2, and so forth are all rational numbers. (By 1/2 we mean the everyday meaning of the fraction, not the integer division this expression would produce in a C++ program.) Represent rational numbers as two values of type int, one for the numerator and one for the denominator. Call the class Rational. Include a constructor with two arguments that can be used to set the member variables of an object to any legitimate values. Also include a constructor that has only a single parameter of type int; call this single parameter wholeNumber and define the constructor so that the object will be initialized to the rational number wholeNumber/1. Also include a default constructor that initializes an object to 0 (that is, 0/1). Overload the input and output operators << and >>. Numbers are to be input and output in the form 1/2, 15/32, 300/401, and so forth. Note that the numerator, the denominator, or both may contain a minus sign, so -1/2, 15/-32, and -300/-401 are also possible inputs. A function to standardize the values stored so that the denominator is always positive should be included. Also write a test program to test your class. */ // ***************************************************************** // // Rationals.cpp // // This program contains a class for rational numbers and a // driver to test the class. The rational class represents a // rational number using two integers - one for the numerator // and one for the denominator. The class has 3 constructors - // a default constructor that sets the number to 1; a constructor // with one integer parameter that sets the rational number to // that integer; a constructor with two integer parameters which // are the numerator and denominator of the rational number. The // class also contains overloaded operators << and >> for output // and input of rational numbers in the format m/n, where m and // n are integers. The driver tests the << and >> operators by // reading in a rational number then printing it out. // // ***************************************************************** #include #include using namespace std; class Rational { public: Rational(); // Initializes the rational number to 0 Rational (int wholeNumber); // Initializes the rational number to wholeNumber/1 Rational (int m, int n); // Initializes the rational number to m/n if n is not 0; // the sign of the rational is stored in the numerator // (the denominator is always positive); // exits if n = 0 (invalid rational number) friend ostream& operator <<(ostream& outs, const Rational& r); // Precondition: If outs is a file output stream, then outs has // already been connected to a file. // Postcondition: The rational number has been sent to the // output stream as numerator slash denominator (with the // denominator always positive). friend istream& operator >>(istream& ins, Rational& r); // Precondition: If ins is a file input stream, then ins has // already been connected to a file. The rational number in // the input stream is in the form of an integer followed by // the slash character followed by an integer. // Postcondition: r has been set to the input value (and // standardized so the denominator is positive). private: int num; // the numerator of the number int denom; // the denominator of the number void standardize(); // Precondition: num and denom have values // Postcondition: if denom is 0 the program is terminated; // otherwise the rational number is standardized so that // denom is positive. }; // ===================== // main function // ===================== int main () { // // Variable declarations // char doAgain; // for the loop control int m, n; // numerator and denominator - m/n Rational r; do { // // Read in a rational number // cout << "Enter a rational number in the form m/n: "; cin >> r; cout << endl; // // Print the number out // cout << "Here's your number: " << r << endl; // // See if the user wants to enter another number // cout << endl << "Enter another number? (y or n): "; cin >> doAgain; cout << endl; } while (doAgain == 'y' || doAgain == 'Y'); // Paul Taylor testing overloaded operators. // Testing Rational(int) Rational a(10); cout << a; Rational b(-10); cout << b; // Testing Rational(int,int) Rational c(10,2); cout << c; Rational d(2,10); cout << d; Rational e(-10,2); cout << e; Rational f(10,-2); cout << f; return 0; } // =========================== // Function Definitions // =========================== Rational::Rational() { num = 0; denom = 1; } Rational::Rational (int wholeNumber) { num = wholeNumber; denom = 1; } Rational::Rational (int m, int n) { num = m; denom = n; } void Rational::standardize() { if (denom < 0) { // denom = -1 * denom; // num = -1 * num; // made code more succint and clear denom = -denom; num = -num; } else if (denom == 0) { cout << "Zero cannot be in the denominator - program aborting!!" << endl; exit(1); } } // -------------------------------- // ----- ENTER YOUR CODE HERE ----- // -------------------------------- ostream& operator <<(ostream& outs, const Rational& r) { if (r.denom < 0) { // Print out opposite signs outs << -(r.num) << "/" << -(r.denom) << endl; } else { outs << r.num << "/" << r.denom << endl; } return outs; } istream& operator >>(istream& ins, Rational& r) { char temp; // setup to hold '/' character ins >> r.num >> temp >> r.denom; r.standardize(); return ins; } // -------------------------------- // --------- END USER CODE -------- // -------------------------------- /* My output Enter a rational number in the form m/n: 5/-2 Here's your number: -5/2 Enter another number? (y or n): y Enter a rational number in the form m/n: -5/2 Here's your number: -5/2 Enter another number? (y or n): y Enter a rational number in the form m/n: -10/-5 Here's your number: 10/5 Enter another number? (y or n): n 10/1 -10/1 10/2 2/10 -10/2 -10/2 Press any key to continue . . . */