📄 complex.cc
字号:
/* Copyright (C) 1988 Free Software Foundation written by Doug Lea (dl@rocky.oswego.edu)This file is part of the GNU C++ Library. This library is freesoftware; you can redistribute it and/or modify it under the terms ofthe GNU Library General Public License as published by the FreeSoftware Foundation; either version 2 of the License, or (at youroption) any later version. This library is distributed in the hopethat it will be useful, but WITHOUT ANY WARRANTY; without even theimplied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULARPURPOSE. See the GNU Library General Public License for more details.You should have received a copy of the GNU Library General PublicLicense along with this library; if not, write to the Free SoftwareFoundation, 675 Mass Ave, Cambridge, MA 02139, USA.*/#ifdef __GNUG__#pragma implementation#endif#include <Complex.h>#include <std.h>#include <builtin.h>// error handlingvoid default_Complex_error_handler(const char* msg){ cerr << "Fatal Complex arithmetic error. " << msg << "\n"; exit(1);}one_arg_error_handler_t Complex_error_handler = default_Complex_error_handler;one_arg_error_handler_t set_Complex_error_handler(one_arg_error_handler_t f){ one_arg_error_handler_t old = Complex_error_handler; Complex_error_handler = f; return old;}void Complex::error(const char* msg) const{ (*Complex_error_handler)(msg);}/* from romine@xagsun.epm.ornl.gov */Complex /* const */ operator / (const Complex& x, const Complex& y){ double den = fabs(y.real()) + fabs(y.imag()); if (den == 0.0) x.error ("Attempted division by zero."); double xrden = x.real() / den; double xiden = x.imag() / den; double yrden = y.real() / den; double yiden = y.imag() / den; double nrm = yrden * yrden + yiden * yiden; return Complex((xrden * yrden + xiden * yiden) / nrm, (xiden * yrden - xrden * yiden) / nrm);}Complex& Complex::operator /= (const Complex& y){ double den = fabs(y.real()) + fabs(y.imag()); if (den == 0.0) error ("Attempted division by zero."); double xrden = re / den; double xiden = im / den; double yrden = y.real() / den; double yiden = y.imag() / den; double nrm = yrden * yrden + yiden * yiden; re = (xrden * yrden + xiden * yiden) / nrm; im = (xiden * yrden - xrden * yiden) / nrm; return *this;}Complex /* const */ operator / (double x, const Complex& y){ double den = norm(y); if (den == 0.0) y.error ("Attempted division by zero."); return Complex((x * y.real()) / den, -(x * y.imag()) / den);}Complex /* const */ operator / (const Complex& x, double y){ if (y == 0.0) x.error ("Attempted division by zero."); return Complex(x.real() / y, x.imag() / y);}Complex& Complex::operator /= (double y){ if (y == 0.0) error ("Attempted division by zero."); re /= y; im /= y; return *this;}Complex /* const */ exp(const Complex& x){ double r = exp(x.real()); return Complex(r * cos(x.imag()), r * sin(x.imag()));}Complex /* const */ cosh(const Complex& x){ return Complex(cos(x.imag()) * cosh(x.real()), sin(x.imag()) * sinh(x.real()));}Complex /* const */ sinh(const Complex& x){ return Complex(cos(x.imag()) * sinh(x.real()), sin(x.imag()) * cosh(x.real()));}Complex /* const */ cos(const Complex& x){ return Complex(cos(x.real()) * cosh(x.imag()), -sin(x.real()) * sinh(x.imag()));}Complex /* const */ sin(const Complex& x){ return Complex(sin(x.real()) * cosh(x.imag()), cos(x.real()) * sinh(x.imag()));}Complex /* const */ log(const Complex& x){ double h = hypot(x.real(), x.imag()); if (h <= 0.0) x.error("attempted log of zero magnitude number."); return Complex(log(h), atan2(x.imag(), x.real()));}// Corrections based on reports from: thc@cs.brown.edu & saito@sdr.slb.comComplex /* const */ pow(const Complex& x, const Complex& p){ double h = hypot(x.real(), x.imag()); if (h <= 0.0) x.error("attempted power of zero magnitude number."); double a = atan2(x.imag(), x.real()); double lr = pow(h, p.real()); double li = p.real() * a; if (p.imag() != 0.0) { lr /= exp(p.imag() * a); li += p.imag() * log(h); } return Complex(lr * cos(li), lr * sin(li));}Complex /* const */ pow(const Complex& x, double p){ double h = hypot(x.real(), x.imag()); if (h <= 0.0) x.error("attempted power of zero magnitude number."); double lr = pow(h, p); double a = atan2(x.imag(), x.real()); double li = p * a; return Complex(lr * cos(li), lr * sin(li));}Complex /* const */ sqrt(const Complex& x){ if (x.real() == 0.0 && x.imag() == 0.0) return Complex(0.0, 0.0); else { double s = sqrt((fabs(x.real()) + hypot(x.real(), x.imag())) * 0.5); double d = (x.imag() / s) * 0.5; if (x.real() > 0.0) return Complex(s, d); else if (x.imag() >= 0.0) return Complex(d, s); else return Complex(-d, -s); }}Complex /* const */ pow(const Complex& x, int p){ if (p == 0) return Complex(1.0, 0.0); else if (x == 0.0) return Complex(0.0, 0.0); else { Complex res(1.0, 0.0); Complex b = x; if (p < 0) { p = -p; b = 1.0 / b; } for(;;) { if (p & 1) res *= b; if ((p >>= 1) == 0) return res; else b *= b; } }}ostream& operator << (ostream& s, const Complex& x){ return s << "(" << x.real() << ", " << x.imag() << ")" ;}istream& operator >> (istream& s, Complex& x){#ifdef _OLD_STREAMS if (!s.good()) { return s; }#else if (!s.ipfx(0)) { s.set(ios::failbit); // Redundant if using GNU iostreams. return s; }#endif double r, i; char ch; s >> ws; s.get(ch); if (ch == '(') { s >> r; s >> ws; s.get(ch); if (ch == ',') { s >> i; s >> ws; s .get(ch); } else i = 0; if (ch != ')') s.clear(_fail); } else { s.putback(ch); s >> r; i = 0; } x = Complex(r, i); return s;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -