189 lines
4.9 KiB
C
189 lines
4.9 KiB
C
|
#pragma once
|
|||
|
#include <cmath>
|
|||
|
#include <iostream>
|
|||
|
|
|||
|
struct Complex {
|
|||
|
float re;
|
|||
|
float im;
|
|||
|
};
|
|||
|
|
|||
|
|
|||
|
// Передаёмм аргументы через ссылки
|
|||
|
// В данном случае можно было передавать по значению
|
|||
|
// (так как Complex имеет малый размер)
|
|||
|
// Но в общем случае лучше для структур лучше
|
|||
|
// всегда использовать ссылки
|
|||
|
|
|||
|
Complex operator+(const Complex& a, const Complex& b) {
|
|||
|
Complex result = {a.re + b.re, a.im + b.im};
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
Complex operator-(const Complex& a, const Complex& b) {
|
|||
|
Complex result = {a.re - b.re, a.im - b.im};
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
Complex operator*(const Complex& a, const Complex& b) {
|
|||
|
Complex result = {a.re * b.re - a.im * b.im, a.re * b.im + a.im * b.re};
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
Complex operator/(const Complex& a, const Complex& b) {
|
|||
|
float b_squared = b.re * b.re + b.im * b.im;
|
|||
|
|
|||
|
Complex result;
|
|||
|
result.re = (a.re * b.re + a.im * b.im) / b_squared;
|
|||
|
result.im = (a.im * b.re - a.re * b.im) / b_squared;
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
Complex& operator+=(Complex &a, const Complex &b) {
|
|||
|
a.re += b.re;
|
|||
|
a.im += b.im;
|
|||
|
return a;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
// Унарный оператор -
|
|||
|
// То есть если z - комплексное число x + iy, то -z = - x - iy
|
|||
|
Complex operator-(const Complex& a) {
|
|||
|
Complex result;
|
|||
|
result.re = -a.re;
|
|||
|
result.im = -a.im;
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
// Унарный оператор +
|
|||
|
// Ничего не меняет
|
|||
|
Complex operator+(const Complex& a) {
|
|||
|
Complex result = a;
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
// Унарный оператор *
|
|||
|
// То есть если z - комплексное число x + iy, то *z = x - iy
|
|||
|
// Оператор сопряжения
|
|||
|
Complex operator*(const Complex& a) {
|
|||
|
Complex result;
|
|||
|
result.re = a.re;
|
|||
|
result.im = -a.im;
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
// Число + комплексное число (в таком порядке)
|
|||
|
Complex operator+(float a, const Complex& b) {
|
|||
|
Complex result = b;
|
|||
|
result.re += a;
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
// Комплексное число + число
|
|||
|
Complex operator+(const Complex& a, float b) {
|
|||
|
Complex result = a;
|
|||
|
result.re += b;
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
// Число - комплексное число (в таком порядке)
|
|||
|
Complex operator-(float a, const Complex& b) {
|
|||
|
Complex result = -b;
|
|||
|
result.re += a;
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
// Комплексное число - число
|
|||
|
Complex operator-(const Complex& a, float b) {
|
|||
|
Complex result = a;
|
|||
|
result.re -= b;
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// Комплексное число * число
|
|||
|
Complex operator*(const Complex& a, float b) {
|
|||
|
Complex result = a;
|
|||
|
result.re *= b;
|
|||
|
result.im *= b;
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
// Число * комплексное число
|
|||
|
Complex operator*(float a, const Complex& b) {
|
|||
|
Complex result = b;
|
|||
|
result.re *= a;
|
|||
|
result.im *= a;
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
// Комплексное число / число
|
|||
|
Complex operator/(const Complex& a, float b) {
|
|||
|
Complex result = a;
|
|||
|
result.re /= b;
|
|||
|
result.im /= b;
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
// Число / комплексное число
|
|||
|
Complex operator/(float a, const Complex& b) {
|
|||
|
float b_squared = b.re * b.re + b.im * b.im;
|
|||
|
return (a * (*b)) / b_squared;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
// Перегружаем оператор<< между типами
|
|||
|
// std::ostream (такой тип имеет std::cout) и Complex
|
|||
|
// Обратите внимание, что мы возвращаем ссылку на ostream
|
|||
|
// Таким образом результатом выражения cout << a будет cout
|
|||
|
// Поэтому можно делать так: cout << a << b << c ...
|
|||
|
std::ostream& operator<<(std::ostream& out, const Complex& a) {
|
|||
|
if (a.re != 0)
|
|||
|
out << a.re;
|
|||
|
|
|||
|
if (a.im > 0) {
|
|||
|
if (a.im != 1.0)
|
|||
|
out << " + " << a.im << "i";
|
|||
|
else
|
|||
|
out << " + i";
|
|||
|
}
|
|||
|
else if (a.im < 0) {
|
|||
|
if (a.im != -1.0)
|
|||
|
out << " - " << -a.im << "i";
|
|||
|
else
|
|||
|
out << " - i";
|
|||
|
}
|
|||
|
return out;
|
|||
|
}
|
|||
|
|
|||
|
std::istream& operator>>(std::istream& in, Complex& c) {
|
|||
|
in >> c.re >> c.im;
|
|||
|
return in;
|
|||
|
}
|
|||
|
|
|||
|
float abs(const Complex& a) {
|
|||
|
return sqrtf(a.re * a.re + a.im * a.im);
|
|||
|
}
|
|||
|
|
|||
|
Complex exp(const Complex& a) {
|
|||
|
Complex result;
|
|||
|
result.re = expf(a.re) * cosf(a.im);
|
|||
|
result.im = expf(a.re) * sinf(a.im);
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
Complex sin(const Complex& a) {
|
|||
|
Complex result;
|
|||
|
result.re = sinf(a.re) * coshf(a.im);
|
|||
|
result.im = cosf(a.re) * sinhf(a.im);
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
Complex cos(const Complex& a) {
|
|||
|
Complex result;
|
|||
|
result.re = cosf(a.re) * coshf(a.im);
|
|||
|
result.im = sinf(a.re) * sinhf(a.im);
|
|||
|
return result;
|
|||
|
}
|