Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

ECS40 Spring 2018 2018-04-12 Homework 1 due Tue 2018-04-24 at 23:59 Use the hand

ID: 3715970 • Letter: E

Question

ECS40 Spring 2018 2018-04-12

Homework 1 due Tue 2018-04-24 at 23:59

Use the handin directory hw1 to submit your work

Fraction calculator

Description

Create a simple fraction calculator that can add and subtract any number of fractions and writes

the answer as a reduced fraction.

Your program will read input from stdin and write output on stdout.

A fraction is represented as the sequence:

a/b

where a and b are integers and any amount of white space characters ' ' (including none) can

separate a from '/' and '/' from b.

Input consists of an expression made of fractions separated by the operators '+' or '-'.

The number of fractions in the expression is arbitrary. Each of the following 6 lines is an

example of valid input expression:

1/2 + 3/4

1/2-5/7+3/5

355/113

3 /9- 21 / -7

4/7-5/-8

-2/-3 +7 /5

Note that the numerator and/or denominator of a fraction given as input may be negative.

The input will consist of a single expression on a single line terminated by a character.

The output should consist of a single, irreducible fraction written as

c/d

where c is a signed integer and d is a positive integer (i.e. the denominator cannot be negative in

the output). The numbers c and d should not have any common factors (apart from 1).

Error processing and special cases

You can expect the input to consist of complete expressions, i.e. there will be no incomplete or

missing fractions in the input. Fractions with a zero denominator may appear in input, and must

cause the following error message to be printed on stdout:

Error: zero denominator

with no other output.

If the answer is an integer, the program should only print that integer and not a fraction

Example: input= 3/2 + 4/8 , output = 2

Examples of input and corresponding output will be provided in the file homework1.tar. Your

output should exactly match the output in the example files (including spaces if any).

Implementation

The main program, called calculator.cpp , is provided. Your project must include a class

Fraction that encapsulates all functions related to the processing of fractions. The >> and <<

operators must be overloaded and used to read and write fractions. The presence of a zero

denominator in input should be handled by throwing an exception of type

invalid_argument defined in <stdexcept>. The class Fraction must be defined in a

source file Fraction.cpp and declared in a header file Fraction.h. The implementation

of the member functions should be defined in the file Fraction.cpp. The class Fraction must

include a constructor Fraction::Fraction(int a, int b). The internal

representation of the fraction should be in reduced form, i.e. using a pair of numbers that have no

common factors. Constructors and other member functions must ensure that the fraction is

always reduced. Use Euclid's algorithm to simplify fractions to reduced form. An example of a C

implementation reduce_fraction.c of this algorithm is provided in the file homework1.tar. Do not

include the file reduce_fraction.c in your submission. The operators '+', '-' and '=' must be

overloaded and defined. Member functions getNum() and getDen() should be implemented,

returning the (reduced) numerator and denominator of the fraction. It should be possible to use

the class Fraction in the program useFraction.cpp which #includes the header

Fraction.h. The program useFraction.cpp is provided in the file homework1.tar. You

should not modify that program.

Submission

Create a tar file named hw1.tar containing the files calculator.cpp Fraction.cpp

Fraction.h useFraction.cpp and Makefile. Do not compress the tar file. The files

calculator.cpp and useFraction.cpp must be identical to the files provided. The

Makefile must contain a target calculator , a target useFraction, a target all, and a

target clean. The target all should appear first and will be used to build both executables.

The target clean will be used to remove all object files and executables. The Makefile

should include the necessary definition to compile C++ files with the –Wall option. Include

your name and Student ID in a comment at the top of each file (except calculator.cpp and

useFraction.cpp). Submit your project using:

$ handin cs40 hw1 hw1.tar

Explanation / Answer

Fraction.h

#include<iostream>
#include<stdexcept>
using namespace std;
//Fraction header file class
class Fraction
{
//Declare priavate variables
private:
int a;
int b;
static int GCD(int a, int b)
{
int min = a < b ? a : b;
int i = 1;
for (i = min; i >= 1; i--)
if (a%i == 0 && b%i == 0)
break;
return i;
}
public:
//Constructor: Fractions with a zero denominator may //appear in input,
//and must cause the following error message to be //printed on stdout:
//Error: division by zero with no other output.
Fraction(int a, int b)
{
if (b == 0) throw invalid_argument("Error: division by zero");
int gcd = GCD(a, b);
this->a = a / gcd;
this->b = b / gcd;
}
//Call the friend functions by using operators.
//Fraction that encapsulates all functions related to //the processing of fractions.
friend Fraction operator+
(const Fraction &f1, const Fraction &f2);
friend Fraction operator-
(const Fraction &f1, const Fraction &f2);
friend bool operator==
(const Fraction &f1, const Fraction &f2);
friend ostream& operator<<
(ostream &out, Fraction &cFraction);
friend istream& operator >>
(istream &in, Fraction &cFraction);
};

Fraction.cpp

#include "Fraction.h"
#include<iostream>
using namespace std;
//Program begins with a main function

// The >> and << operators must be overloaded and used to read and
//write fractions. The presence of a zero denominator in input should
//be handled by throwing an exception of type invalid_argument defined in.
ostream& operator<< (ostream &out, Fraction &cFraction)
{
if (cFraction.b == 1)
out << cFraction.a << endl;
else
out << cFraction.a << " / " << cFraction.b;
return out;
}
istream& operator >> (istream &in, Fraction &cFraction)
{
in >> cFraction.a >> cFraction.b;
if (cFraction.b == 0) throw invalid_argument("Error: division by zero");
int gcd = Fraction::GCD(cFraction.a, cFraction.b);
cFraction.a = cFraction.a / gcd;
cFraction.b = cFraction.b / gcd;
return in;
}

//Use Euclid's algorithm to simplify fractions to reduced form. The operators '+', '-'
//and '=' must be overloaded and defined.
Fraction operator+(const Fraction &f1, const Fraction &f2)
{
//Declare variables
int n, d, gcd;
//Calculate + operator value
n = f1.a*f2.b + f2.a*f1.b;
d = f1.b*f2.b;
gcd = Fraction::GCD(n, d);
return Fraction(n / gcd, d / gcd);
}
Fraction operator-(const Fraction &f1, const Fraction &f2)
{
//Declare variables
int n, d, gcd;
//Calculate - operator value
n = f1.a*f2.b - f2.a*f1.b;
d = f1.b*f2.b;
gcd = Fraction::GCD(n, d);
return Fraction(n / gcd, d / gcd);
}
bool operator==(const Fraction &f1, const Fraction &f2)
{
return (f1.a*f2.b == f2.a*f1.b);
}

useFraction.cpp:

#include "Fraction.h"
using namespace std;
int main()
{
//Call the methods
Fraction x(3, 2);
Fraction y(4, 8);
//Display x, y values
cout << "Input values: ";
cout << x << endl;
cout << y << endl;
//Calculate fraction value
Fraction z = x + y;
//Display output
cout << "Result: " << x << " + " << y << " = " << z << endl;
//Pause the system for a while
system("PAUSE");
return 0;
}

calculator.cpp:

  #include "Fraction.h"
  
  using namespace std;
  
  
  int main()
  {
    int a=1,b=2,c=2,d=3;
      cin >>a;
   cin >>b;
    cin >>c;
    cin >>d;
    Fraction x(a,b);
    Fraction y(c,d);
  
      char op;
    try
    {
     
      cin >> op;
      while ( cin && ( op == '+' || op == '-' ) )
      {
       
        if ( op == '+' )
        {
       
        Fraction z = x + y;
         cout << z << endl;
        }else
        {
    
        Fraction z = x - y;
            cout << z << endl;}cin >> op;
      }
  
    }
    catch ( invalid_argument& e )
    {
      cout << "Error: " << e.what() << endl;
    }
  }

Only one main can execute at a time .

make file while executing calculator main function (comment the useFraction file):

# Project: Project1
# Makefile created by Dev-C++ 5.11

CPP      = g++.exe -D__DEBUG__
CC       = gcc.exe -D__DEBUG__
WINDRES = windres.exe
OBJ      = FRACTION.o useFraction.o calculator.o
LINKOBJ = FRACTION.o useFraction.o calculator.o
LIBS     = -L"C:/Program Files (x86)/Dev-Cpp/MinGW64/lib" -L"C:/Program Files (x86)/Dev-Cpp/MinGW64/x86_64-w64-mingw32/lib" -static-libgcc -g3
INCS     = -I"C:/Program Files (x86)/Dev-Cpp/MinGW64/include" -I"C:/Program Files (x86)/Dev-Cpp/MinGW64/x86_64-w64-mingw32/include" -I"C:/Program Files (x86)/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include"
CXXINCS = -I"C:/Program Files (x86)/Dev-Cpp/MinGW64/include" -I"C:/Program Files (x86)/Dev-Cpp/MinGW64/x86_64-w64-mingw32/include" -I"C:/Program Files (x86)/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include" -I"C:/Program Files (x86)/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include/c++"
BIN      = Project1.exe
CXXFLAGS = $(CXXINCS) -g3
CFLAGS   = $(INCS) -g3
RM       = rm.exe -f

.PHONY: all all-before all-after clean clean-custom

all: all-before $(BIN) all-after

clean: clean-custom
${RM} $(OBJ) $(BIN)

$(BIN): $(OBJ)
$(CPP) $(LINKOBJ) -o $(BIN) $(LIBS)

FRACTION.o: FRACTION.cpp
$(CPP) -c FRACTION.cpp -o FRACTION.o $(CXXFLAGS)

useFraction.o: useFraction.cpp
$(CPP) -c useFraction.cpp -o useFraction.o $(CXXFLAGS)

calculator.o: calculator.cpp
$(CPP) -c calculator.cpp -o calculator.o $(CXXFLAGS)