Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

At the end of this work you should submit a header file Complex.h, with the class interface, function declarations, and constexpr function definitions, and Complex.cpp

At the end of this work you should submit a header file Complex.h, with the class interface, function declarations, and constexpr function definitions, and Complex.cpp that includes all the other implementations.

Before you panic (if you are math-phobic), this is not really about the math. All the math information you need to solve the homework is given in this document. Just read it carefully. Were effectively going to work with special numbers with special rules (that are given to you) for how +, -, *, and / work.

Background: real numbers are the numbers everyone is familiar with in daily life: -4.3, 19, 27, , etc.

The complex numbers are pairs of real numbers (a, b) often written in the form

a + bi

where i is called the imaginary unit. If z is a complex number and z = a + bi, we call a the real part of z and b the imaginary part of z.

There are some special rules for their arithmetic. You dont need to know why, all you need to know is what these rules dictate. Suppose that a, b, c, and d are real numbers. Then:

(a + bi) + (c + di) = (a + c) + (b + d)i so, for example (4 + 3i) + (1 6i) = (4 + 1) + (3 6)i = 5 3i.

(a+bi)(c+di) = (ac)+(bd)i so, for example, i(23i) = (0+1i)(23i) = (0 2) + (1 (3))i = 2 + 4i.

(a + bi)(c + di) = (ac bd) + (bc + ad)i so, for example, (1 + i)(2 + i) = 1 + 3i.

(a + bi)/(c + di) = ac+bd c 2+d 2 + bcad c 2+d 2 i so, for example, 1+i 3+4i = 7 25 1 25 i.

Given a complex number z = a + bi, we refer to the process of switching the sign of the imaginary part as complex conjugation and write it as z = a bi.

In this homework, you will need to write a Complex class to represent complex numbers and overload many operators for the Complex class to behave just like normal arithmetic. You should also make heavy use of constexpr. Everything that can be constexpr should be.

Firstly, your Complex class should have

two floating point (use double!!!) private member variables to store the real and imaginary parts; and

a single constexpr constructor that, through the use of default arguments, behaves as a default constructor that sets both the real and imaginary parts to 0; when given a single double as a parameter, the real part is set to this value and the imaginary part is set to 0; and when given two double inputs, it sets the real and imaginary parts to these values in respective order.

Then, you should overload

binary operator+= to add two complex numbers, changing the left-hand side;

binary operator+ to add two complex numbers, returning the sum;

unary operator+ to return a copy of the complex number;

operator++, both prefix (unary) and postfix (binary), such that the real part (and only the real part) is incremented by 1;

binary operator-= to subtract two complex numbers, changing the left-hand side;

binary operator- to subtract two complex numbers, returning the difference;

unary operator- to return a complex number with negated real and imaginary parts;

operator- -, both prefix (unary) and postfix (binary), such that the real part (and only the real part) is decremented by 1;

binary operator*= to multiply two complex numbers, changing the left-hand side;

binary operator* to multiply two complex numbers, returning the product;

binary operator/= to divide two complex numbers, changing the left-hand side;

binary operator/ to divide two complex numbers, returning the quotient;

unary operator to return the conjugate of the complex number;

a call operator taking no arguments setting the complex number to 0;

a subscript operator overloaded on const taking either real or imag as arguments and returning the real or imaginary parts of the number respectively (possibly as references), and should the subscript be invalid an std::out of range exception should be thrown, without being caught, with an error description invalid index: [WHATEVER THE BAD INDEX WAS];

operator<< to print/display the complex number with an output stream such that if the imaginary part is positive it should be displayed as "a+bi"; if the imaginary part is negative, it should be displayed in the format "a-bi"; and if the imaginary part is 0, then is hosuld be displayed as "a";

operator>> to read in two double values, separated by white space, respectively setting the real and imaginary parts of the complex number on the right-hand side of an input stream;

all of the comparison operators operator<, operator==, operator>, operator<=. operator>=operator!= such that a + bi and c + di are compared lexicographically, i.e., by first comparing the real parts numerically and then the imaginary parts numerically if necessary (3 + 4i < 3.1 + 4i, 1 i < 1 0.5i, 4 + i = 4 + i, etc.)*;

a conversion operator from Complex to std::string (if the real part is 7 and the imaginary part is -8.36 then the output should be 7-8.36i, etc.); and

a user-defined literal expression so that a code expression such as 3.3 i will be converted into the complex number 0+3.3i.

* mathematically, there is no ordering of the complex numbers in that no mathematical definition of < can satisfy the axioms of an ordered field. That doesnt mean we cant order the numbers in a way that is intuitive for a user of the class as we do here.

To reiterate on the formatting: a number with 0 real and 0 imaginary part should display as 0; a number with a real part of 5 and an imaginary part of -3 should display as 5-3i; a number with a real part of -1 and an imaginary part of +4.4 should display as -1+4.4i; etc. There should not be unnecessary 0s floating around after a decimal 3 (-1+4.40000 is not acceptable, for example).

Further requirements:

You may only use the following headers:

iostream

string

sstream

stdexcept

In particular, you may not use the header!

You must adhere to the conventions in class with regards to which operators are member/nonmember functions.

Given the main routine below, the output is provided.

#include "Complex.h" #include #include #include int main(){ // some warmups Complex u{ 2,3 }, v{ 1,1 }; std::cout << "simple stuff: " << u + v << ' ' << u - v << ' ' << u*v << ' ' << u / v << ' '; // constexptr stuff constexpr Complex z0 = 1.77_i; constexpr Complex z0_conj = ~z0; constexpr Complex z0_copy = +z0; constexpr Complex z0_negated = -z0; // display this constexpr stuff std::cout << "z0, z0 conj, z0 copy, z0 neg: " << z0 << " " << z0_conj << " " << z0_copy << " " << z0_negated << ' '; // Create Complex numbers through constructors constexpr Complex z1, z2{ 3, 4 }; constexpr Complex z3 = (Complex{1} += (4 - 3._i)); Complex z4 = z3; z4 *= 2; // multiply by 2 (which will be converted to Complex(2,0) // Create with user-defined literal Complex z5 = 3.14 + 14.3_i; std::cout << "Numbers z1, z2, z3, z4, z5: " << z1 << " " << z2 << " " << z3 << " " << z4 << " " << z5 << ' '; // turn z5 to its conjugate z5 = ~z5; std::cout << "z5 after conjugation: " << z5 << ' '; std::cout << "z5*z3: " << z5*z3 << ' '; // Do some arithmetic to them and check values z4 += z3; z4 /= z5; Complex z6 = z1 + z2 + z3 - z4; Complex z7 = z6; z7(); std::cout << "z4, z5, z6, z7: " << z4 << " " << z5 << " " << z6 << " " << z7 << ' '; // And read in with std::cin std::cout << "Enter two doubles to set real and imaginary parts: "; std::cin >> z4; std::cout << "-z4 and +z5: " << -z4 << " " << +z5 << ' '; // Access real and imaginary parts z4["real"] = 0.14; std::cout << "real(z4) and imag(z4): " << z4["real"] << " " << z4["imag"] << ' '; // increment and decrement operators ++++z4, z5------; std::cout << "z4 with two pre++ and z5 with 3 post--: " << z4 << " " << z5 << ' '; // store items in a vector, sort them std::vector vec{ z1, z2, z3, z4, z5, z6, z7 }; // vector of complex std::vector vec2{ z1, z2, z3, z4, z5, z6, z7 }; // vector of strings because of conversion operator std::cout << "The elements: "; for (const std::string& complexString : vec2) { // print each as a string std::cout << complexString << " "; } std::sort(std::begin(vec), std::end(vec)); // sort the Complex numbers std::cout << " sorted vector: "; for (const Complex& number : vec) { // print the sorted list std::cout << number << " "; } std::cout << ' '; try{ // try accessing invalid index z2["reel"]; } catch (const std::out_of_range& ORR){ // upon failure, print the error and continue to run the program std::cerr << ORR.what() << ' '; } // access real part of a constant number const Complex z8 = z7; std::cout << "z8 imag: " << z8["imag"]; std::cin.get(); std::cin.get(); return 0; }

Some initial guidance to get you on your way...

1. Your literal operator should take a long double as an input.

2. To do the std::string conversion, you should use a string stream and good old operator<<. But to suitably overload operator<< and adhere to the formatting requirements, you may need to condition what you display based on the sign of the imaginary part.

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Database Internals A Deep Dive Into How Distributed Data Systems Work

Authors: Alex Petrov

1st Edition

1492040347, 978-1492040347

More Books

Students also viewed these Databases questions

Question

1. Let a, b R, a Answered: 1 week ago

Answered: 1 week ago