Lab 5 Extra

Write a class Complex with the following declaration and part implementation.

The class will implement the following operators:

  1. op+, op-, op*

These will accept 2 complex number, a complex number and a real number, or a real number and a complex number. (9 in total)

  1. op- unary
  2. op== si op!=
  3. op<< stream operators for printing
  4. op++ prefixed and postfixed and op-- prefixed and postfixed
  5. op() with the below semantics total: 18 operators

op++ postfixed MUST use op++ prefixed

op-- postfixed MUST use op-- prefixed

#pragma once

#include <ostream>

class Complex {
  private:
    double real_data;
    double imag_data;

  public:
    Complex();
    Complex(double real, double imag);

    bool is_real() const;

    double real() const;
    double imag() const;
    double abs() const;
    Complex conjugate() const;

    Complex& operator()(double real, double imag);
};

Complex operator+(const Complex& l, const Complex& r);
Complex operator+(const Complex& l, double r);
Complex operator+(double l, const Complex& r);

Complex operator-(const Complex& obj);

bool operator==(const Complex& l, const Complex& r);

std::ostream& operator<<(std::ostream& out, const Complex& complex);
#include "complex.h"

Complex::Complex() : Complex(0, 0) {
}

Complex::Complex(double real, double imag) {
    real_data = real;
    imag_data = imag;
}

bool Complex::is_real() const {
    return imag() == 0;
}

double Complex::real() const {
    return real_data;
}

double Complex::imag() const {
    return imag_data;
}

double Complex::abs() const {
    return sqrt(real() * real() + imag() * imag());
}

Complex Complex::conjugate() const {
    return { real(), -imag() };
}

The follosing main.cpp file must compile and work at runtime.

#include <iostream>p

#include <cmath>
#include "complex.h"

bool double_equals(double l, double r) {
    return abs(l - r) < 0.001;
}

#define check(x)                                                                                                       \
    if (!(x)) {                                                                                                        \
        printf("at line #%d -> `%s` is not satisfied\n", __LINE__, #x);                                                \
        return 1;                                                                                                      \
    }

int main() {
    Complex a{ 1, 2 };
    check(double_equals(a.real(), 1));
    check(double_equals(a.imag(), 2));

    Complex b{ 2, 3 };
    Complex c = a + b;
    check(double_equals(c.real(), 3));
    check(double_equals(c.imag(), 5));

    Complex d = c - a;
    check(b == d);

    Complex e = (a * d).conjugate();
    check(double_equals(e.imag(), -7));

    {
        // increment the real part
        Complex res1 = e++;
        check(res1 == e - 1);
        Complex& res2 = ++e;
        check(res2 == e);
        check(double_equals(e.real(), -2));
    }

    {
        // decrement the real part
        Complex res1 = e--;
        check(res1 == e + 1);
        Complex& res2 = --e;
        check(res2 == e);
        check(double_equals(e.real(), -4));
    }

    Complex f = (a + b - d) * c;
    if (f != Complex{ 1, 2 }) {
        // prints in the format a +/i bi
        // if a or b are not 0, they won't be printed
        // if they're both 0, 0 will be printed
        // examples:                 5 + 4i
        //                          -3 - 2i
        //                          -6
        //                           5i
        std::cout << f << '\n' << a << '\n';
        std::cout << Complex{ 1, 2 } << '\n'
                  << Complex{ 1, -2 } << '\n'
                  << Complex{ 0, 5 } << '\n'
                  << Complex{ 7, 0 } << '\n'
                  << Complex{ 0, 0 } << '\n';
    }

    // op() will update the real part and the imaginary part
    // it will behave as a setter for both
    Complex g = f(-1, -2)(-2, -3)(-4, -5);
    Complex h = { -4, -5 };
    check(g == h);

    Complex i = h - (h + 5) * 2;
    check(double_equals(i.real(), -6));

    // unary op-
    Complex j = -i + i;
    check(double_equals(j.abs(), 0));
}