0

CSCI-15 Assignment #4, operator functions/methods. 25 points. Due 11/6/2013

Extend your class MixedExpression class to include operator methods for addition, subtraction, multiplication and division, and to have friend operator << and operator >> functions for reading and printing the MixedExpression objects. Allow cascaded input and output per the << and >> operators in the standard I/O routines. Do not change your original add(), etc., methods, just add the new functionality.

Write a new version of the calculator to loop reading MixedExpression objects and operators and performing the indicated operations. Read and print the input and output using the same << and >> notation as if you were writing a calculator for integers.
If you did the original MixedExpression class and calculator correctly, this will be easy.

Here is my header file (MixedExpression.h):

#ifndef MIXEDEXPRESSION_H
#define MIXEDEXPRESSION_H
#include<fstream>
using namespace std;

class MixedExpression
{
    private:
        long a, b, c; // Variables of the mixed expression.
         // Reduce a mixed expression to its normal form.
        void reduce(void);
    public:
        MixedExpression(); // Default constructor.
        MixedExpression(long, long, long); // Normal constructor.
         // Add two mixed expressions.
        MixedExpression add(MixedExpression op);
         // Subtract two mixed expressions.
        MixedExpression subtract(MixedExpression op);
         // Multiply two mixed expressions.
        MixedExpression multiply(MixedExpression op);
         // Divide two mixed expressions.
        MixedExpression divide(MixedExpression op);
        void ReadMixedExp(istream &in); // Read each line.
        void printData(ostream &out); // Print the result.
        MixedExpression operator + (MixedExpression op);
        MixedExpression operator - (MixedExpression op);
        MixedExpression operator * (MixedExpression op);
        MixedExpression operator / (MixedExpression op);
    friend istream &operator >> (istream &, MixedExpression &);
    friend ostream &operator << (ostream &, MixedExpression &);
};
#endif

Here is my library source file (MixedExpression.cpp):

#include "MixedExpression.h"
#include<iostream>
#include<fstream>
using namespace std;

// Convert a mixed expression to its normal form.
void MixedExpression::reduce(void)
{
    long numerator = a*c + b; // Holds the numerator.
    long remainder = numerator % c; // Holds the remainder.
    long dividend = numerator / c; // Holds the dividend.
    long gcd = 1; // Holds the greatest common divisor.

    // Get the greatest common divisor.
    for (int i = 2; i <= remainder; i++)
    {
        if((c % i == 0) && (remainder % i == 0))
        {
            gcd = i;
        }
    }
    remainder /= gcd; // Divide the remainder by the GCD.
    c /= gcd; // Divide the denominator (c = denominator) by the GCD.
    a = dividend; // Set a equal to the dividend.
    b = remainder; // Set b equal to the remainder.
    if(b == 0) // If b is zero, set to default.
    {
        c = 1;
    }
}

// Set the first two values in the default constructor to 0
// and the third value to 1.
MixedExpression::MixedExpression()
{
    a = 0;
    b = 0;
    c = 1;
}

// Set three values in the normal constructor equal to the arguments.
MixedExpression::MixedExpression(long d, long e, long f)
{
    a = d;
    b = e;
    c = f;
}

// Add two mixed expressions and return the result.
MixedExpression MixedExpression::add(MixedExpression op)
{
    MixedExpression res;
    res.a = a + op.a;
    res.b = (b * op.c) + (op.b * c);
    res.c = c * op.c;
    return MixedExpression(res.a,res.b,res.c);
}

// Subtract two mixed expressions and return the result.
MixedExpression MixedExpression::subtract(MixedExpression op)
{
    MixedExpression res;
    res.a = a - op.a;
    res.b = (b * op.c) - (op.b * c);
    res.c = c * op.c;
    return MixedExpression(res.a,res.b,res.c);
}

// Multiply two mixed expressions and return the result.
MixedExpression MixedExpression::multiply(MixedExpression op)
{
    long numerator;
    long denominator;
    long remainder;
    MixedExpression res;

    numerator = (a*c + b) * (op.a * op.c + op.b);
    denominator = c * op.c;
    remainder = numerator % denominator;
    res.a = numerator/denominator;
    return MixedExpression(res.a,remainder,denominator);
}

// Divide two mixed expressions and return the result.
MixedExpression MixedExpression::divide(MixedExpression op)
{
    long numerator;
    long denominator;
    long remainder;
    MixedExpression res;

    numerator = (a*c + b) * (op.c);
    denominator = c * (op.a * op.c + op.b);
    remainder = numerator % denominator;
    res.a = numerator/denominator;
    return MixedExpression(res.a,remainder,denominator);
}

// Read each value and character.
void MixedExpression::ReadMixedExp(istream &in)
{
    char remove;
    in >> remove >> a >> remove >> b >> remove >> c >> remove;
}

// Print the results.
void MixedExpression::printData(ostream &out)
{
    reduce();
    out << "( " << a << " + " << b << " / " << c << " )";
}

MixedExpression MixedExpression::operator + (MixedExpression op)
{
    add(op);
}

MixedExpression MixedExpression::operator - (MixedExpression op)
{
    subtract(op);
}

MixedExpression MixedExpression::operator * (MixedExpression op)
{
    multiply(op);
}

MixedExpression MixedExpression::operator / (MixedExpression op)
{
    divide(op);
}

istream &operator >> (istream &in, MixedExpression &op)
{
    op.ReadMixedExp(in);
}

ostream &operator << (ostream &out, MixedExpression &op)
{
    op.printData(out);
}

Here is my calculator client file (Calculator.cpp):

#include "MixedExpression.h"
#include<iostream>
#include<fstream>
using namespace std;

int main(int argc, char *argv[])
{
    MixedExpression res;
    MixedExpression op1;
    MixedExpression op2; 
    char symbol;
    ifstream in;
    ofstream out;

    if(argc != 3)
    {
        cout << "Usage: program input-file output-file" << endl;
        return 1; // Return error code.
    }
    in.open(argv[1]); // Open input file on command line.
    out.open(argv[2]); // Open output file on command line.
    if(!in || !out) // Check if the files opened successfully.
    {
        cout << "There was an error opening the files!" << endl;
        return 1;
    }
    while(!in.eof())
    { 
        in >> op1 >> symbol >> op2;
        switch(symbol)
        {
            case '+': res = op1 + op2;
                break;
            case '-': res = op1 - op2;
                break;
            case '*': res = op1 * op2;
                break;
            case '/': res = op1 / op2;
                break;
        }
        out << op1 << " " << symbol << " " << op2 << " = " << res << endl;
    }
    // Close the input file.
    in.close();
    // Close the output file.
    out.close();
    return 0;
}

Here are my input lines:

( 1 + 2 / 6 ) + ( 3 + -3 / 9 )
( 3 + 5 / 9 ) + ( 2 + 3 / 7 )
( 0 + 0 / 1 ) + ( 1 + 0 / 1 )
( 7 + -3 / 9 ) - ( 3 + 7 / 8 )
( 3 + 2 / 5 ) - ( 1 + 4 / 7 )
( 1 + 0 / 1 ) - ( 0 + 0 / 1 )
( 7 + 5 / 25 ) * ( 4 + -6 / 14 )
( 3 + 1 / 4 ) * ( 1 + 2 / 6 )
( 1 + 0 / 1 ) * ( 0 + 0 / 1 )
( 4 + 4 / 5 ) / ( 2 + 3 / 6 )
( 8 + 3 / 4 ) / ( 2 + 1 / 3 )
( 0 + 0 / 1 ) / ( 1 + 0 / 1 )

The expected output I am trying to get is this:

( 1 + 1 / 3 ) + ( 2 + 2 / 3 ) = ( 4 + 0 / 1 )
( 3 + 5 / 9 ) + ( 2 + 3 / 7 ) = ( 5 + 62 / 63 )
( 0 + 0 / 1 ) + ( 1 + 0 / 1 ) = ( 1 + 0 / 1 )
( 6 + 2 / 3 ) - ( 3 + 7 / 8 ) = ( 2 + 19 / 24 )
( 3 + 2 / 5 ) - ( 1 + 4 / 7 ) = ( 1 + 29 / 35 )
( 1 + 0 / 1 ) - ( 0 + 0 / 1 ) = ( 1 + 0 / 1 )
( 7 + 1 / 5 ) * ( 3 + 4 / 7 ) = ( 25 + 5 / 7 )
( 3 + 1 / 4 ) * ( 1 + 1 / 3 ) = ( 4 + 1 / 3 )
( 1 + 0 / 1 ) * ( 0 + 0 / 1 ) = ( 0 + 0 / 1 )
( 4 + 4 / 5 ) / ( 2 + 1 / 2 ) = ( 1 + 23 / 25 )
( 8 + 3 / 4 ) / ( 2 + 1 / 3 ) = ( 3 + 3 / 4 )
( 0 + 0 / 1 ) / ( 1 + 0 / 1 ) = ( 0 + 0 / 1 )
( 0 + 0 / 1 ) / ( 1 + 0 / 1 ) = ( 0 + 0 / 1 )

Now all I am getting is this:

( 1 + 1 / 3 ) + ( 2 + 2 / 3 ) = ( -94 + -446902 / 2293064 )
( 3 + 5 / 9 ) + ( 2 + 3 / 7 ) = ( -94 + -446902 / 2293064 )
( 0 + 0 / 1 ) + ( 1 + 0 / 1 ) = ( -94 + -446902 / 2293064 )
( 6 + 2 / 3 ) - ( 3 + 7 / 8 ) = ( -94 + -446902 / 2293064 )
( 3 + 2 / 5 ) - ( 1 + 4 / 7 ) = ( -94 + -446902 / 2293064 )
( 1 + 0 / 1 ) - ( 0 + 0 / 1 ) = ( -94 + -446902 / 2293064 )
( 7 + 1 / 5 ) * ( 3 + 4 / 7 ) = ( -94 + -446902 / 2293064 )
( 3 + 1 / 4 ) * ( 1 + 1 / 3 ) = ( -94 + -446902 / 2293064 )
( 1 + 0 / 1 ) * ( 0 + 0 / 1 ) = ( -94 + -446902 / 2293064 )
( 4 + 4 / 5 ) / ( 2 + 1 / 2 ) = ( -94 + -446902 / 2293064 )
( 8 + 3 / 4 ) / ( 2 + 1 / 3 ) = ( -94 + -446902 / 2293064 )
( 0 + 0 / 1 ) / ( 1 + 0 / 1 ) = ( -94 + -446902 / 2293064 )
( 0 + 0 / 1 ) / ( 1 + 0 / 1 ) = ( -94 + -446902 / 2293064 )

I think the calculations are not coming out correct because in the overloading operator methods, I am not calling the add(), subtract(), multiply(), and divide() methods correctly. How can I call them correctly in the operator methods in order to get the correct output?

2
Contributors
1
Reply
30
Views
4 Years
Discussion Span
Last Post by Ancient Dragon
0

The return value of each of those functions may be incorrect. All they have to do is return res, they don't have to create another object

MixedExpression MixedExpression::add(MixedExpression op)
{
    MixedExpression res;
    res.a = a + op.a;
    res.b = (b * op.c) + (op.b * c);
    res.c = c * op.c;
    return res; // <<<<<<<<<<<<<<<<<<
}
This question has already been answered. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.