In: Computer Science
Task
Create a class called Mixed. Objects of type Mixed will store and manage rational numbers in a mixed number format (integer part and a fraction part). The class, along with the required operator overloads, should be written in the files mixed.h and mixed.cpp.
Details and Requirements
Finish Lab 2 by creating a Mixed class definition with constructor functions and some methods.
The Mixed class should have public member functions Evaluate(), ToFraction(), and Simplify(). The Evaluate() function should return a double, the others don’t return anything. These functions have no parameters. The names must match the ones here exactly. They should do the following:
Create an overload of the extraction operator >> for reading mixed numbers from an input stream. The input format for a Mixed number object will be:
integer numerator/denominator
i.e. the integer part, a space, and the fraction part (in numerator/denominator form), where the integer, numerator, and denominator parts are all of type int. You may assume that this will always be the format that is entered (i.e. your function does not have to handle entry of incorrect types that would violate this format). However, this function should check the values that come in. In the case of an incorrect entry, just set the Mixed object to represent the number 0, as a default. An incorrect entry occurs if a denominator value of 0 is entered, or if an improper placement of a negative sign is used. Valid entry of a negative number should follow this rule - if the integer part is non-zero, the negative sign is entered on the integer part; if the integer part is 0, the negative sign is entered on the numerator part (and therefore the negative sign should never be in the denominator). Examples:
Valid inputs: 2 7/3 , -5 2/7 , 4 0/7 , 0 2/5 , 0 -8/3
Invalid inputs: 2 4/0 , -2 -4/5 , 3 -6/3 , 0 2/-3
Create an overload of the insertion operator << for output of Mixed numbers. This should output the mixed number in the same format as above, with the following exceptions: If the object represents a 0, then just display a 0. Otherwise: If the integer part is 0, do not display it. If the fraction part equals 0, do not display it. For negative numbers, the minus sign is always displayed to the left.
Examples: 0 , 2 , -5 , 3/4 , -6/7 , -2 4/5 , 7 2/3
Create operator overloads for the 4 standard arithmetic operations ( + , - , * , / ) , to perform addition, subtraction, multiplication, and division of two mixed numbers. Each of these operators will perform its task on two Mixed objects as operands and will return a Mixed object as a result - using the usual meaning of arithmetic operations on rational numbers. Also, each of these operators should return their result in simplified form. (e.g. return 3 2/3 instead of 3 10/15, for example).
Use function __gcd (you need to add #include <algorithm>) for calculation of the greatest common divisor) for simplification of the fractions. For subtraction and division, you can use inverse rules to simplify your code, see Inverse of rational number.
In the division operator, if the second operand is 0, this would yield an invalid result. Since we have to return something from the operator, return 0 as a default (even though there is no valid answer in this case). Example:
Mixed m(1, 2, 3); // value is 1 2/3 Mixed z; // value is 0 Mixed r = m / z; // r is 0 (even though this is not good math)
Create overloads for the increment and decrement operators (++ and –). You need to handle both the pre- and post- forms (pre-increment, post-increment, pre-decrement, post-decrement). These operators should have their usual meaning – increment will add 1 to the Mixed value, decrement will subtract 1. Example:
Mixed m1(1, 2, 3); // 1 2/3 Mixed m2(2, 1, 2); // 2 1/2 cout << m1++; // prints 1 2/3, m1 is now 2 2/3 cout << ++m1; // prints 3 2/3, m1 is now 3 2/3 cout << m2--; // prints 2 1/2, m2 is now 1 1/2 cout << --m2; // prints 1/2 , m2 is now 0 1/2
Driver Program
The sample driver program that is provided can be found below. Note, this is not a comprehensive set of tests. It is just some code to get you started, illustrating some sample calls.
#include <iostream>
#include "mixed.h"
using namespace std;
int main(){
Mixed m0(1, 1, 1); // 1 1/1 == 2
m0.Simplify();
cout << m0 << endl; // prints 2
m0.ToFraction();
cout << m0 << endl; // prints 2/1
Mixed m1(1, 2, 3); // 1 2/3
m1.Print(); // prints 1 2/3
cout << m1++ << endl; // prints 1 2/3, m1 is now 2
2/3
cout << ++m1 << endl; // prints 3 2/3, m1 is now 3
2/3
Mixed m2(2, 5, 3); // 2 5/3
cout << m2 << endl; // prints 2 5/3
cout << m2.Evaluate() << endl; // prints 3.6666
m2.Simplify(); // m2 is now 3 2/3
cout << m2 << endl; // prints 3 2/3
Mixed m3 = m1 + m2; // m3 is now 7 1/3
cout << m3 << endl; // prints 7 1/3
cout << m3.Evaluate() << endl; // prints 7.3333
Mixed m4(1, 2, 3); // 1 2/3
m4.ToFraction();
cout << m4 << endl; // prints 5/3
Mixed m5 = m4 + Mixed(1);
cout << m5 << endl; // prints 2 2/3
Mixed m6(1);
cout << m6 << endl; // prints 1
m6.ToFraction();
cout << m6 << endl; // prints 1/1
cout << m6-m4 << endl; // prints -2/3
Mixed m7(0,3,4);
cout << m5*m7 << endl; // prints 2 (= 8/3 * 3/4)
cout << m5/m7 << endl; // prints 3 5/9 (32/9 = 8/3 *
4/3)
cout << "m4 == m4: " << boolalpha << (m4 == m4)
<< endl;
cout << "m5 != m4: " << boolalpha << (m5 != m4)
<< endl;
cout << "m5 > m4: " << boolalpha << (m5 >
m4) << endl;
cout << "m5 >= m4: " << boolalpha << (m5 >=
m4) << endl;
cout << "m4 < m5: " << boolalpha << (m4 <
m5) << endl;
cout << "m4 <= m4: " << boolalpha << (m4 <=
m4) << endl;
}
/*** Mixed.h ***/
#ifndef MIXED_H
#define MIXED_H
#include<iostream>
using namespace std;
//Mixed class
class Mixed
{
private:
/* private members */
int wholeNum;
int numer;
int denom;
public:
Mixed(int=0);
Mixed(int,int,int);
void ToFraction();
double Evaluate();
void Simplify();
void Print();
bool operator==(const Mixed &num);
bool operator!=(const Mixed &num);
bool operator<(const Mixed &num);
bool operator<=(const Mixed &num);
bool operator>(const Mixed &num);
bool operator>=(const Mixed &num);
Mixed operator+(const Mixed &num);
Mixed operator-(const Mixed &num);
Mixed operator*(const Mixed &num);
Mixed operator/(const Mixed &num);
Mixed& operator++();
Mixed operator++(int);
Mixed& operator--();
Mixed operator--(int);
friend istream& operator>>(istream &is, Mixed
&num);
friend ostream& operator<<(ostream &os, const Mixed
&num);
};
#endif
/*** Mixed.cpp ***/
#include <iostream>
#include <algorithm>
#include"Mixed.h"
using namespace std;
//default constructor
Mixed::Mixed(int num)
{
wholeNum = num;
numer = 0;
denom = 1;
}
//parameterized constructor
Mixed::Mixed(int wNum,int num, int den)
{
wholeNum = wNum;
numer = num;
denom = den;
}
//function to simplify the mixed number
void Mixed::Simplify()
{
int gcd = __gcd( numer , denom);
if(denom <= 0 || (wholeNum < 0 && numer <
0))
{
wholeNum = 0;
numer = 0;
denom = 1;
}
else
{
wholeNum = numer/ denom + wholeNum;
numer %= denom;
numer /= gcd;
denom /= gcd;
}
}
//convert the mixed number into fraction form
void Mixed::ToFraction()
{
numer = wholeNum * denom + numer;
wholeNum = 0;
}
//function return the decimal equivalent of the mixed
number.
double Mixed::Evaluate()
{
double num = wholeNum * denom + numer;
return num/denom;
}
// print function
void Mixed::Print()
{
if(numer==0){
cout<<wholeNum;
}
if(wholeNum!=0)
cout << wholeNum<<" ";
cout<< numer << "/"<< denom<<endl;
}
// == operator overloading function
bool Mixed::operator==(const Mixed &num)
{
return wholeNum==num.wholeNum && numer==num.numer
&& denom==num.denom;
}
// != operator overloading function
bool Mixed::operator!=(const Mixed &num)
{
return wholeNum!=num.wholeNum || numer!=num.numer ||
denom!=num.denom;
}
// < operator overloading function
bool Mixed::operator<(const Mixed &num)
{
if(wholeNum<num.wholeNum) return true;
if(wholeNum==num.wholeNum)
{
if(numer*num.denom<denom*num.numer)
return true;
return false;
}
return false;
}
// <= operator overloading function
bool Mixed::operator<=(const Mixed &num)
{
if(*this==num || *this<num)
return true;
return false;
}
// > operator overloading function
bool Mixed::operator>(const Mixed &num)
{
if(wholeNum>num.wholeNum) return true;
if(wholeNum==num.wholeNum)
{
if(numer*num.denom>denom*num.numer)
return true;
return false;
}
return false;
}
// >= operator overloading function
bool Mixed::operator>=(const Mixed &num)
{
if(*this==num || *this>num)
return true;
return false;
}
// + operator overloading function
Mixed Mixed::operator+(const Mixed &num)
{
Mixed temp;
temp.wholeNum = wholeNum + num.wholeNum;
temp.numer = numer*num.denom + denom*num.numer;
temp.denom = denom * num.denom;
temp.Simplify();
return temp;
}
// - operator overloading function
Mixed Mixed::operator-(const Mixed &num)
{
Mixed temp;
temp.wholeNum = wholeNum - num.wholeNum;
temp.numer = numer*num.denom - denom*num.numer;
temp.denom = denom * num.denom;
temp.Simplify();
return temp;
}
// * operator overloading function
Mixed Mixed::operator*(const Mixed &num)
{
Mixed temp;
temp.wholeNum = 0;
temp.numer = (wholeNum * denom + numer) * (num.wholeNum * num.denom
+ num.numer);
temp.denom = denom * num.denom;
temp.Simplify();
return temp;
}
// prefix increment operator overloading
Mixed& Mixed::operator++()
{
wholeNum = wholeNum + 1;
return *this;
}
// postfix increment operator overloading
Mixed Mixed::operator++(int a)
{
Mixed tmp(*this);
wholeNum = wholeNum + 1;
return tmp;
}
// prefix decrement operator overloading
Mixed& Mixed::operator--()
{
wholeNum = wholeNum - 1;
return *this;
}
// postfix decrement operator overloading
Mixed Mixed::operator--(int a)
{
Mixed tmp(*this);
wholeNum = wholeNum - 1;
return tmp;
}
// / operator overloading function
Mixed Mixed::operator/(const Mixed &num)
{
if(num.wholeNum==0 && num.numer==0)
return num;
Mixed temp;
temp.wholeNum = 0;
temp.numer = (wholeNum * denom + numer) * num.denom;
temp.denom = denom * (num.wholeNum * num.denom + num.numer);
temp.Simplify();
return temp;
}
// >> operator overloading function
istream& operator>>(istream &is, Mixed
&num)
{
is>>num.wholeNum>>num.numer>>num.denom;
num.Simplify();
return is;
}
// << operator overloading function
ostream& operator<<(ostream &os, const Mixed
&num)
{
if(num.numer==0){
os<<num.wholeNum;
return os;
}
if(num.wholeNum!=0)
os << num.wholeNum<<" ";
os<< num.numer << "/"<< num.denom;
return os;
}
/*** main.cpp ***/
#include <iostream>
#include"Mixed.h"
using namespace std;
//main function
int main(){
Mixed m0(1, 1, 1); // 1 1/1 == 2
m0.Simplify();
cout << m0 << endl; // prints 2
m0.ToFraction();
cout << m0 << endl; // prints 2/1
Mixed m1(1, 2, 3); // 1 2/3
m1.Print(); // prints 1 2/3
cout << m1++ << endl; // prints 1 2/3, m1 is now 2
2/3
cout << ++m1 << endl; // prints 3 2/3, m1 is now 3
2/3
Mixed m2(2, 5, 3); // 2 5/3
cout << m2 << endl; // prints 2 5/3
cout << m2.Evaluate() << endl; // prints 3.6666
m2.Simplify(); // m2 is now 3 2/3
cout << m2 << endl; // prints 3 2/3
Mixed m3 = m1 + m2; // m3 is now 7 1/3
cout << m3 << endl; // prints 7 1/3
cout << m3.Evaluate() << endl; // prints 7.3333
Mixed m4(1, 2, 3); // 1 2/3
m4.ToFraction();
cout << m4 << endl; // prints 5/3
Mixed m5 = m4 + Mixed(1);
cout << m5 << endl; // prints 2 2/3
Mixed m6(1);
cout << m6 << endl; // prints 1
m6.ToFraction();
cout << m6 << endl; // prints 1/1
cout << m6-m4 << endl; // prints -2/3
Mixed m7(0,3,4);
cout << m5*m7 << endl; // prints 2 (= 8/3 * 3/4)
cout << m5/m7 << endl; // prints 3 5/9 (32/9 = 8/3 *
4/3)
cout << "m4 == m4: " << boolalpha << (m4 == m4)
<< endl;
cout << "m5 != m4: " << boolalpha << (m5 != m4)
<< endl;
cout << "m5 > m4: " << boolalpha << (m5 >
m4) << endl;
cout << "m5 >= m4: " << boolalpha << (m5 >=
m4) << endl;
cout << "m4 < m5: " << boolalpha << (m4 <
m5) << endl;
cout << "m4 <= m4: " << boolalpha << (m4 <=
m4) << endl;
}
Output:
Whether you face any
difficulties regarding this assignment please let me know through
the comments. I will try my best to assist you. However if you are
satisfied with the answer please don't forget to give your
feedback.