A template to answer this homework is provided. It contains five files:

  • Fracs.hpp and Fracs.cpp contain the Frac class which I defined. The class interface is in the .hpp file. Any leftover member function definitions appear in the YOU SHOULD NOT CHANGE THESE TWO FILES.
  • You may notice that I have destroyed the default constructor. I have done this on purpose. YOU ARE NOT ALLOWED TO FIX THIS. So do not ever call the default constructor for Frac explicitly or implicitly (by not using an initializer list in ComplexFrac).
  • main.cpp contains some demonstration code. You can edit this file as much as you like, and you should edit this file in order to test the functionality of the new class that you create.
  • ComplexFracs.hpp and ComplexFracs.cpp are the files which you will turn in.
  • Currently there is a declaration of a class called ComplexFrac in the .hpp file. It has two private member variables: real and imag. It has one public constructor with no parameters which creates an instance of ComplexFrac with real==0 and imag==0. It has one public member function called print. The definition of print is given in the .cpp file. You should read and understand what it is doing.

The goal of this question is to add more functionality to the class ComplexFrac so that it can perform complex number arithmetic (amongst other things).

A complex number is a number of the form a + bi where a and b are real numbers. a is called the real part and b is called the imaginary part. In order to use the Frac class from lectures, we will take a and b to be fractions. All you need to know about complex numbers to answer this question is that a + bi = c+ di exactly when a = c and b = d, and +, -, , / are defined as follows:

(a + bi) + (c + di) = (a + c) + (b + d)i
(a + bi) - (c + di) = (a - c) + (b - d)i
(a + bi) x (c + di) = (ac – bd) + (ad + bc)i
(a + bi) / (c + di) = (a + bi) x (((c / (c2 + d2)) + (-d / (c2 + d2)))i)

Notice that I have defined division in term of multiplication. Look over the page for your list of tasks!

1. Constructors

I have already given ComplexFrac a default constructor. Define four more constructors:

  • The first should have 1 parameter of type Frac.
  • The second should have 2 parameters of type Frac.
  • The third should have 1 parameter of type int.
  • The fourth should have 4 parameters of type int.

What should they do? You can hopefully guess, but....

  • The first is for constructing a complex number with imaginary part equal to 0.
  • The second does the "obvious" thing.
  • The third takes an integer n and constructs the complex number (n/1) + (0/1)i. (just like how when I wrote Frac, one constructor used n to construct the fraction n/1). It should help to recall the different constructors that Frac has.
  • The fourth takes ints renum, reden, imnum, imden to make mum. It should help to recall the different constructors that Frac has.

Why do you think I chose not to make a constructor using two ints?

2. Comparison

Define a member function isEqual that performs a similar job to the function of the same name belonging to Frac.

3. Arithmetic

Declare member functions add, subtract, multiply, and divide in the .hpp file. If the parameters and/or return type are unclear, look back to what I did with Frac. Define these member functions in the .cpp file.

You should expect defining multiplication and division to be a bit awkward. In some ways, it would be easier if we had overloaded the +, -, *, / operators, but we're delaying a detailed discussion of such things until PIC 10B.

Your division function can call your multiplication function once you create (((c / (c2 + d2)) + (-d / (c2 + d2)))i)

4. Public versus private

The member functions you defined in 1-3 should all be public. If you need to use auxilary functions, they should be private.

THERE SHOULD BE NO PUBLIC MEMBER VARIABLES.

THERE SHOULD BE NO PUBLIC GETTERS OR SETTERS.

5. Const. correctness

Make sure that you are const correct.

6. Testing

Make sure to use your main.cpp to test your functions. Wolfram Alpha has a good complex number calculator.

Starter Codes

Fracs.hpp

#ifndef Fracs_hpp
#define Fracs_hpp

#include < iostream >
#include < cassert >
#include < algorithm >

class Frac {
public:
Frac(int _num) : num(_num), den(1) { }
Frac(int _num, int _den) : num(_num), den(_den) {
assert(den != 0);
makeDenomPos(); Msimplify();
}

Frac() : num(0), den(1) {
std::cout << "You just called the default constructor " << std::endl;
std::cout << "for Frac. If you think that you didn't, " << std::endl;
std::cout << "ask yourself whether you failed to use an " << std::endl;
std::cout << "initializer list when you should have done." << std::endl;
std::cout << "If you did intend to use the default " << std::endl;
std::cout << "constructor, don't! Remember... I broke it!" << std::endl;
exit(1);
}

void print() const { std::cout << num; if (den != 1) { std::cout << "/" << den; } }

Frac add(const Frac& other) const;
Frac subtract(const Frac& other) const;
Frac multiply(const Frac& other) const;
Frac divide(const Frac& other) const;

// The following functions make use of the fact that
// all of our fractions have positive denominators
// and that they are simplified as much as possible.
bool isEqual(const Frac& other) const { return (num == other.num) && (den == other.den); }

bool isZero() const { return num == 0; }
bool isPositive() const { return num > 0; }

private:
int num;
int den;

void makeDenomPos() { if (den < 0) { num *= -1; den *= -1; } }
void makeZeroNice() { if (num == 0) { den = 1; } }

void simplify();
void Msimplify(); // Michael's simplify - uses the Euclidean algorithm
};

#endif /* Fracs_hpp */

ComplexFracs.hpp

#ifndef ComplexFracs_hpp
#define ComplexFracs_hpp

#include "Fracs.hpp"

class ComplexFrac
{
public:
ComplexFrac()
: real(0), imag(0)
{
}

ComplexFrac(const Frac &real)
: real(real), imag(0)
{
}

ComplexFrac(const Frac &real, const Frac &imag)
: real(real), imag(imag)
{
}

ComplexFrac(int n)
{
real = Frac(n, 1);
imag = Frac(0, 1);
}

ComplexFrac(int realN, int realD, int imagN, int imagD)
{
real = Frac(realN, realD);
imag = Frac(imagN, imagD);
}

bool isEqual(const ComplexFrac &other) const;

ComplexFrac add(const ComplexFrac &other) const;
ComplexFrac subtract(const ComplexFrac &other) const;
ComplexFrac multiply(const ComplexFrac &other) const;
ComplexFrac divide(const ComplexFrac &other) const;

void print() const;

private:
Frac real;
Frac imag;
};

#endif /* ComplexFracs_hpp */
Academic Honesty!
It is not our intention to break the school's academic policy. Posted solutions are meant to be used as a reference and should not be submitted as is. We are not held liable for any misuse of the solutions. Please see the frequently asked questions page for further questions and inquiries.
Kindly complete the form. Please provide a valid email address and we will get back to you within 24 hours. Payment is through PayPal, Buy me a Coffee or Cryptocurrency. We are a nonprofit organization however we need funds to keep this organization operating and to be able to complete our research and development projects.