4.6. Операции с комплексными числами
4.6. Операции с комплексными числами
Класс комплексных чисел стандартной библиотеки С++ представляет собой хороший пример использования объектной модели. Благодаря перегруженным арифметическим операциям объекты этого класса используются так, как будто они принадлежат одному из встроенных типов данных. Более того, в подобных операциях могут одновременно принимать участие и переменные встроенного арифметического типа, и комплексные числа. (Отметим, что здесь мы не рассматриваем общие вопросы математики комплексных чисел. См. [PERSON68] или любую книгу по математике.) Например, можно написать:
#inc1ude complex
comp1ex double a;
comp1ex double b;
// ...
complex double с = a * b + a / b;
Комплексные и арифметические типы разрешается смешивать в одном выражении:
complex double complex_obj = a + 3.14159;
Аналогично комплексные числа инициализируются арифметическим типом, и им может быть присвоено такое значение:
double dval = 3.14159;
complex_obj = dval;
Или
int ival = 3;
complex_obj = ival;
Однако обратное неверно. Например, следующее выражение вызовет ошибку компиляции:
// ошибка: нет неявного преобразования
// в арифметический тип
double dval = complex_obj;
Нужно явно указать, какую часть комплексного числа – вещественную или мнимую – мы хотим присвоить обычному числу. Класс комплексных чисел имеет две функции, возвращающих соответственно вещественную и мнимую части. Мы можем обращаться к ним, используя синтаксис доступа к членам класса:
double re = complex_obj.real();
double im = complex_obj.imag();
или эквивалентный синтаксис вызова функции:
double re = real(complex_obj);
double im = imag(complex_obj);
Класс комплексных чисел поддерживает четыре составных оператора присваивания: +=, -=, *= и /=. Таким образом,
complex_obj += second_complex_obj;
Поддерживается и ввод/вывод комплексных чисел. Оператор вывода печатает вещественную и мнимую части через запятую, в круглых скобках. Например, результат выполнения операторов вывода
complex double complex0( 3.14159, -2.171 );
comp1ex double complex1( complexO.real() );
cout complexO " " complex1 endl;
выглядит так:
( 3.14159, -2.171 ) ( 3.14159, 0.0 )
Оператор ввода понимает любой из следующих форматов:
// допустимые форматы для ввода комплексного числа
// 3.14159 == comp1ex( 3.14159 );
// ( 3.14159 ) == comp1ex( 3.14159 );
// ( 3.14, -1.0 ) == comp1ex( 3.14, -1.0 );
// может быть считано как
// cin a b с
// где a, b, с - комплексные числа
3.14159 ( 3.14159 ) ( 3.14, -1.0 )
Кроме этих операций, класс комплексных чисел имеет следующие функции-члены: sqrt(), abs(), polar(), sin(), cos(), tan(), exp(), log(), log10() и pow().
Упражнение 4.9
Реализация стандартной библиотеки С++, доступная нам в момент написания книги, не поддерживает составных операций присваивания, если правый операнд не является комплексным числом. Например, подобная запись недопустима:
complex_obj += 1;
(Хотя согласно стандарту С++ такое выражение должно быть корректно, производители часто не успевают за стандартом.) Мы можем определить свой собственный оператор для реализации такой операции. Вот вариант функции, реализующий оператор сложения для complexdouble:
#include complex
operator+=( complexdouble cval, double dval )
{
return cval += complexdouble( dval );
}
(Это пример перегрузки оператора для определенного типа данных, детально рассмотренной в главе 15.)
Используя этот пример, реализуйте три других составных оператора присваивания для типа complexdouble. Добавьте свою реализацию к программе, приведенной ниже, и запустите ее для проверки.
#include iostream
#include complex
// определения операций...
int main() {
complex double cval ( 4.0, 1.0 );
cout cval endl;
cval += 1;
cout cval endl;
cval -= 1;
cout cval endl;
cval *= 2;
cout cval endl;
cout /= 2;
cout cval endl;
}
Упражнение 4.10
Стандарт С++ не специфицирует реализацию операций инкремента и декремента для комплексного числа. Однако их семантика вполне понятна: если уж мы можем написать:
cval += 1;
что означает увеличение на 1 вещественной части cval, то и операция инкремента выглядела бы вполне законно. Реализуйте эти операции для типа complexdouble и выполните следующую программу:
#include iostream
#include complex
// определения операций...
int main() {
complex double cval( 4.0, 1.0 );
cout cval endl;
++cva1;
cout cval endl;
}