/****************************************************************************** * This program demonstrates the Complex Number class. * * Copyright © 2021 Richard Lesh. All rights reserved. *****************************************************************************/ #undef NDEBUG #include "Utils.hpp" #include #include #include #include #include #include std::locale utf8loc(std::locale(), new std::codecvt_utf8); using namespace Utils; using namespace std; class Complex { private: // Internal representation for a complex number is two doubles double real = 0.0; double imaginary = 0.0; public: // Constructor Complex(double r, double i) noexcept { real = r; imaginary = i; } shared_ptr add(shared_ptr const x) noexcept { return shared_ptr(new Complex(real + x->real, imaginary + x->imaginary)); } shared_ptr sub(shared_ptr const x) noexcept { return shared_ptr(new Complex(real - x->real, imaginary - x->imaginary)); } shared_ptr mul(shared_ptr const x) noexcept { return shared_ptr(new Complex(real * x->real - imaginary * x->imaginary, real * x->imaginary + imaginary * x->real)); } shared_ptr recip() noexcept { double const MAG_SQUARED = real * real + imaginary * imaginary; return shared_ptr(new Complex(real / MAG_SQUARED, -imaginary / MAG_SQUARED)); } shared_ptr div(shared_ptr const x) noexcept { return this->mul(x->recip()); } double abs() noexcept { double const MAG_SQUARED = real * real + imaginary * imaginary; return sqrt(MAG_SQUARED); } double phase() noexcept { double const MAGNITUDE = this->abs(); if (real < 0. && imaginary == 0.) { return M_PI; } return 2. * atan(imaginary / (MAGNITUDE + real)); } shared_ptr csqrt() noexcept { double const MAG = this->abs(); double const r = sqrt((real + MAG) / 2.); double i = sqrt((-real + MAG) / 2.); i *= ((imaginary > 0) ? 1 : ((imaginary < 0) ? -1 : 0)); return shared_ptr(new Complex(r, i)); } shared_ptr cexp() noexcept { double const MAG = exp(real); return shared_ptr(new Complex(MAG * cos(imaginary), MAG * sin(imaginary))); } shared_ptr clog() noexcept { double const MAG = this->abs(); return shared_ptr(new Complex(log(MAG), phase())); } wstring to_string() noexcept { if (real == 0.0) { return to_wstring(imaginary) + wstring(L"i"); } else if (imaginary == 0.0) { return to_wstring(real); } else if (imaginary < 0) { return to_wstring(real) + to_wstring(imaginary) + wstring(L"i"); } else { return to_wstring(real) + wstring(L"+") + to_wstring(imaginary) + wstring(L"i"); } } }; int main(int argc, char **argv) { setlocale(LC_ALL, "en_US.UTF-8"); wcout.imbue(utf8loc); wcin.imbue(utf8loc); shared_ptr a(new Complex(1., 1.)); shared_ptr b(new Complex(3., 4.)); wcout << L"a: " << a->to_string() << endl; wcout << L"b: " << b->to_string() << endl; wcout << L"a + b: " << a->add(b)->to_string() << endl; wcout << L"a - b: " << a->sub(b)->to_string() << endl; wcout << L"a * b: " << a->mul(b)->to_string() << endl; wcout << L"1 / a: " << a->recip()->to_string() << endl; wcout << L"1 / b: " << b->recip()->to_string() << endl; wcout << L"a / b: " << a->div(b)->to_string() << endl; wcout << L"|a|: " << a->abs() << endl; wcout << L"|b|: " << b->abs() << endl; wcout << L"φ(a): " << a->phase() << endl; wcout << L"φ(b): " << b->phase() << endl; wcout << L"sqrt(a): " << a->csqrt()->to_string() << endl; wcout << L"sqrt(b): " << b->csqrt()->to_string() << endl; wcout << L"exp(a): " << a->cexp()->to_string() << endl; wcout << L"exp(b): " << b->cexp()->to_string() << endl; wcout << L"ln(a): " << a->clog()->to_string() << endl; wcout << L"ln(b): " << b->clog()->to_string() << endl; return 0; }