You'll receive 4 homework throughout the semester. We expect you to submit a .zip archive (not a .rar, not a .7zip, not a .tgz). The archive should meet the following criteria:
- Naming convention: hw<homework_number>.group<group_number>.<fn>.zip where:
-
<homework_number> is the number of the current homework
-
<group_number> is the number of your group ([O, rly?][1])
-
<fn> is your faculty number
That's ok: hw3.group2.66666.zip
That's not: hw3.g2.66666.zip, hw3.group2.fn66666.zip, hw3.group2.66666.rar
- Contents: you should only submit source and header files (.h, .cpp) and NOTHING else, no folders, no executables, no .dll-s, no .lib-s, no .o-s, nothing else
Failing to meet any of the above will get you 0 points. Now for the interesting stuff.
You are to implement a struct for working with Complex numbers
Create a Complex
struct (cause we prefer structs to classes when it comes down to immutability) that supports all arithmetic operations on complex numbers. Namely, your struct should have the following public inteface:
// An immutable struct for working with complex numbers.
// See example usage below.
struct Complex
{
public:
// Returns the number i (0 + i)
static Complex GetI();
// Constructs a default Complex number (0 + 0i)
Complex();
// Constructs a Complex number with no imaginary part (real + 0i)
Complex(double real);
// Constructs a Complex number with predefined values (real + imaginary * i)
Complex(double real, double imaginary);
// Returns the real part of the complex number
double Real() const;
// Returns the imaginary part of the complex number
double Imaginary() const;
// Computes the conjugate (���������) of the complex number
Complex& Conjugate() const;
// Computes the modulus (distance to the center of the coordinate system) of the complex number
double Modulus() const;
// Computes the n-th power of the complex number. Use de Moivre's formulae
Complex Power(double n) const;
// Computes the k-th, n-th root of the complex number (remember that a complex number has multiple n-th roots, you should only return the root with index k, indices start from 0)
Complex Root(double n, double k) const;
// Computes the argument of the complex number (the angle between its radius-vector and Ox). Should be in the range [0; 2pi]
double Argument() const;
// Returns true if the number is real (i.e. b = 0)
bool IsReal() const;
};
// Adds two numbers
Complex operator+(const Complex& p, const Complex& q);
// Substracts two numbers
Complex operator-(const Complex& p, const Complex& q);
// Multiplies two numbers
Complex operator*(const Complex& p, const Complex& q);
// Divides two numbers. Complex division MUST be defined using ONLY multiplication, conjugate and modulus
Complex operator/(const Complex& p, const Complex& q);
// Computes the nth power of the Complex number. MUST be defined using only the Power method (aliases are cool)
Complex operator^(const Complex& number, double n);
// Returns true if the numbers are equal (lhs = left hand side, rhs = right hand side)
bool operator==(const Complex& lhs, const Complex& rhs);
// Returns true if the numbers are not equal
bool operator!=(const Complex& lhs, const Complex& rhs);
// Reads a complex number from the stream. The input will be in the form a + bi
std::istream& operator>>(std::istream& stream, Complex& number);
// Writes a complex number to the stream. The output should be in the form 'a + bi'. If b = 1, the output should be 'a + i' and if b = 0, the output should be only 'a'.
std::ostream& operator<<(std::ostream& stream, const Complex& number);
Your struct MUST be IMMUTABLE with the ONLY exception of that rule being the input operator (std::istream& operator>>(std::istream& stream, Complex& number)
). In other words, say that p
is an instance of Complex
. Then no method or field should be able to change the values of p
's real and imaginary parts besides the operator that reads from the console.
Complex one(1, 0),
two(2, 0),
unit(1, 1),
sample(4, -5),
i = Complex::GetI();
cout << (one.Real() == 1); // true;
cout << (i.Imaginary() == 0); // false;
cout << one + two; // 3
cout << two - one; // 1
cout << sample + i; // 4 - 4i
cout << one * i; // 0 + i
cout << one / i; // 0 - i;
cout << one.Root(2, 0); // 1
cout << one.Root(2, 1); // -1
cout << one.Root(4, 2); // 0 + i
cout << i.Power(2); // -1
cout << (i ^ 2); // -1
cout << (sample + 2 * i).Modulus(); // 5
cout << (i == Complex(0, 1)); // true
cout << (unit == one + i); // true
cout << (sample != i); // true