Whole document tree std_complex.hGo to the documentation of this file.00001 // The template and inlines for the -*- C++ -*- complex number classes. 00002 00003 // Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. 00004 // 00005 // This file is part of the GNU ISO C++ Library. This library is free 00006 // software; you can redistribute it and/or modify it under the 00007 // terms of the GNU General Public License as published by the 00008 // Free Software Foundation; either version 2, or (at your option) 00009 // any later version. 00010 00011 // This library is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU General Public License for more details. 00015 00016 // You should have received a copy of the GNU General Public License along 00017 // with this library; see the file COPYING. If not, write to the Free 00018 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 00019 // USA. 00020 00021 // As a special exception, you may use this file as part of a free software 00022 // library without restriction. Specifically, if other files instantiate 00023 // templates or use macros or inline functions from this file, or you compile 00024 // this file and link it with other files to produce an executable, this 00025 // file does not by itself cause the resulting executable to be covered by 00026 // the GNU General Public License. This exception does not however 00027 // invalidate any other reasons why the executable file might be covered by 00028 // the GNU General Public License. 00029 00030 // 00031 // ISO C++ 14882: 26.2 Complex Numbers 00032 // Note: this is not a conforming implementation. 00033 // Initially implemented by Ulrich Drepper <drepper@cygnus.com> 00034 // Improved by Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr> 00035 // 00036 00037 #ifndef _CPP_COMPLEX 00038 #define _CPP_COMPLEX 1 00039 00040 #pragma GCC system_header 00041 00042 #include <bits/c++config.h> 00043 #include <bits/cpp_type_traits.h> 00044 #include <bits/std_cmath.h> 00045 #include <bits/std_sstream.h> 00046 00047 namespace std 00048 { 00049 // Forward declarations 00050 template<typename _Tp> class complex; 00051 template<> class complex<float>; 00052 template<> class complex<double>; 00053 template<> class complex<long double>; 00054 00055 template<typename _Tp> _Tp abs(const complex<_Tp>&); 00056 template<typename _Tp> _Tp arg(const complex<_Tp>&); 00057 template<typename _Tp> _Tp norm(const complex<_Tp>&); 00058 00059 template<typename _Tp> complex<_Tp> conj(const complex<_Tp>&); 00060 template<typename _Tp> complex<_Tp> polar(const _Tp&, const _Tp&); 00061 00062 // Transcendentals: 00063 template<typename _Tp> complex<_Tp> cos(const complex<_Tp>&); 00064 template<typename _Tp> complex<_Tp> cosh(const complex<_Tp>&); 00065 template<typename _Tp> complex<_Tp> exp(const complex<_Tp>&); 00066 template<typename _Tp> complex<_Tp> log(const complex<_Tp>&); 00067 template<typename _Tp> complex<_Tp> log10(const complex<_Tp>&); 00068 template<typename _Tp> complex<_Tp> pow(const complex<_Tp>&, int); 00069 template<typename _Tp> complex<_Tp> pow(const complex<_Tp>&, const _Tp&); 00070 template<typename _Tp> complex<_Tp> pow(const complex<_Tp>&, 00071 const complex<_Tp>&); 00072 template<typename _Tp> complex<_Tp> pow(const _Tp&, const complex<_Tp>&); 00073 template<typename _Tp> complex<_Tp> sin(const complex<_Tp>&); 00074 template<typename _Tp> complex<_Tp> sinh(const complex<_Tp>&); 00075 template<typename _Tp> complex<_Tp> sqrt(const complex<_Tp>&); 00076 template<typename _Tp> complex<_Tp> tan(const complex<_Tp>&); 00077 template<typename _Tp> complex<_Tp> tanh(const complex<_Tp>&); 00078 00079 00080 // 26.2.2 Primary template class complex 00081 template<typename _Tp> 00082 class complex 00083 { 00084 public: 00085 typedef _Tp value_type; 00086 00087 complex(const _Tp& = _Tp(), const _Tp & = _Tp()); 00088 00089 // Let's the compiler synthetize the copy constructor 00090 // complex (const complex<_Tp>&); 00091 template<typename _Up> 00092 complex(const complex<_Up>&); 00093 00094 _Tp real() const; 00095 _Tp imag() const; 00096 00097 complex<_Tp>& operator=(const _Tp&); 00098 complex<_Tp>& operator+=(const _Tp&); 00099 complex<_Tp>& operator-=(const _Tp&); 00100 complex<_Tp>& operator*=(const _Tp&); 00101 complex<_Tp>& operator/=(const _Tp&); 00102 00103 // Let's the compiler synthetize the 00104 // copy and assignment operator 00105 // complex<_Tp>& operator= (const complex<_Tp>&); 00106 template<typename _Up> 00107 complex<_Tp>& operator=(const complex<_Up>&); 00108 template<typename _Up> 00109 complex<_Tp>& operator+=(const complex<_Up>&); 00110 template<typename _Up> 00111 complex<_Tp>& operator-=(const complex<_Up>&); 00112 template<typename _Up> 00113 complex<_Tp>& operator*=(const complex<_Up>&); 00114 template<typename _Up> 00115 complex<_Tp>& operator/=(const complex<_Up>&); 00116 00117 private: 00118 _Tp _M_real, _M_imag; 00119 }; 00120 00121 template<typename _Tp> 00122 inline _Tp 00123 complex<_Tp>::real() const { return _M_real; } 00124 00125 template<typename _Tp> 00126 inline _Tp 00127 complex<_Tp>::imag() const { return _M_imag; } 00128 00129 template<typename _Tp> 00130 inline 00131 complex<_Tp>::complex(const _Tp& __r, const _Tp& __i) 00132 : _M_real(__r), _M_imag(__i) { } 00133 00134 template<typename _Tp> 00135 template<typename _Up> 00136 inline 00137 complex<_Tp>::complex(const complex<_Up>& __z) 00138 : _M_real(__z.real()), _M_imag(__z.imag()) { } 00139 00140 template<typename _Tp> 00141 complex<_Tp>& 00142 complex<_Tp>::operator=(const _Tp& __t) 00143 { 00144 _M_real = __t; 00145 _M_imag = _Tp(); 00146 return *this; 00147 } 00148 00149 // 26.2.5/1 00150 template<typename _Tp> 00151 inline complex<_Tp>& 00152 complex<_Tp>::operator+=(const _Tp& __t) 00153 { 00154 _M_real += __t; 00155 return *this; 00156 } 00157 00158 // 26.2.5/3 00159 template<typename _Tp> 00160 inline complex<_Tp>& 00161 complex<_Tp>::operator-=(const _Tp& __t) 00162 { 00163 _M_real -= __t; 00164 return *this; 00165 } 00166 00167 // 26.2.5/5 00168 template<typename _Tp> 00169 complex<_Tp>& 00170 complex<_Tp>::operator*=(const _Tp& __t) 00171 { 00172 _M_real *= __t; 00173 _M_imag *= __t; 00174 return *this; 00175 } 00176 00177 // 26.2.5/7 00178 template<typename _Tp> 00179 complex<_Tp>& 00180 complex<_Tp>::operator/=(const _Tp& __t) 00181 { 00182 _M_real /= __t; 00183 _M_imag /= __t; 00184 return *this; 00185 } 00186 00187 template<typename _Tp> 00188 template<typename _Up> 00189 complex<_Tp>& 00190 complex<_Tp>::operator=(const complex<_Up>& __z) 00191 { 00192 _M_real = __z.real(); 00193 _M_imag = __z.imag(); 00194 return *this; 00195 } 00196 00197 // 26.2.5/9 00198 template<typename _Tp> 00199 template<typename _Up> 00200 complex<_Tp>& 00201 complex<_Tp>::operator+=(const complex<_Up>& __z) 00202 { 00203 _M_real += __z.real(); 00204 _M_imag += __z.imag(); 00205 return *this; 00206 } 00207 00208 // 26.2.5/11 00209 template<typename _Tp> 00210 template<typename _Up> 00211 complex<_Tp>& 00212 complex<_Tp>::operator-=(const complex<_Up>& __z) 00213 { 00214 _M_real -= __z.real(); 00215 _M_imag -= __z.imag(); 00216 return *this; 00217 } 00218 00219 // 26.2.5/13 00220 // XXX: This is a grammar school implementation. 00221 template<typename _Tp> 00222 template<typename _Up> 00223 complex<_Tp>& 00224 complex<_Tp>::operator*=(const complex<_Up>& __z) 00225 { 00226 const _Tp __r = _M_real * __z.real() - _M_imag * __z.imag(); 00227 _M_imag = _M_real * __z.imag() + _M_imag * __z.real(); 00228 _M_real = __r; 00229 return *this; 00230 } 00231 00232 // 26.2.5/15 00233 // XXX: This is a grammar school implementation. 00234 template<typename _Tp> 00235 template<typename _Up> 00236 complex<_Tp>& 00237 complex<_Tp>::operator/=(const complex<_Up>& __z) 00238 { 00239 const _Tp __r = _M_real * __z.real() + _M_imag * __z.imag(); 00240 const _Tp __n = norm(__z); 00241 _M_imag = (_M_imag * __z.real() - _M_real * __z.imag()) / __n; 00242 _M_real = __r / __n; 00243 return *this; 00244 } 00245 00246 // Operators: 00247 template<typename _Tp> 00248 inline complex<_Tp> 00249 operator+(const complex<_Tp>& __x, const complex<_Tp>& __y) 00250 { return complex<_Tp> (__x) += __y; } 00251 00252 template<typename _Tp> 00253 inline complex<_Tp> 00254 operator+(const complex<_Tp>& __x, const _Tp& __y) 00255 { return complex<_Tp> (__x) += __y; } 00256 00257 template<typename _Tp> 00258 inline complex<_Tp> 00259 operator+(const _Tp& __x, const complex<_Tp>& __y) 00260 { return complex<_Tp> (__y) += __x; } 00261 00262 template<typename _Tp> 00263 inline complex<_Tp> 00264 operator-(const complex<_Tp>& __x, const complex<_Tp>& __y) 00265 { return complex<_Tp> (__x) -= __y; } 00266 00267 template<typename _Tp> 00268 inline complex<_Tp> 00269 operator-(const complex<_Tp>& __x, const _Tp& __y) 00270 { return complex<_Tp> (__x) -= __y; } 00271 00272 template<typename _Tp> 00273 inline complex<_Tp> 00274 operator-(const _Tp& __x, const complex<_Tp>& __y) 00275 { return complex<_Tp> (__x) -= __y; } 00276 00277 template<typename _Tp> 00278 inline complex<_Tp> 00279 operator*(const complex<_Tp>& __x, const complex<_Tp>& __y) 00280 { return complex<_Tp> (__x) *= __y; } 00281 00282 template<typename _Tp> 00283 inline complex<_Tp> 00284 operator*(const complex<_Tp>& __x, const _Tp& __y) 00285 { return complex<_Tp> (__x) *= __y; } 00286 00287 template<typename _Tp> 00288 inline complex<_Tp> 00289 operator*(const _Tp& __x, const complex<_Tp>& __y) 00290 { return complex<_Tp> (__y) *= __x; } 00291 00292 template<typename _Tp> 00293 inline complex<_Tp> 00294 operator/(const complex<_Tp>& __x, const complex<_Tp>& __y) 00295 { return complex<_Tp> (__x) /= __y; } 00296 00297 template<typename _Tp> 00298 inline complex<_Tp> 00299 operator/(const complex<_Tp>& __x, const _Tp& __y) 00300 { return complex<_Tp> (__x) /= __y; } 00301 00302 template<typename _Tp> 00303 inline complex<_Tp> 00304 operator/(const _Tp& __x, const complex<_Tp>& __y) 00305 { return complex<_Tp> (__x) /= __y; } 00306 00307 template<typename _Tp> 00308 inline complex<_Tp> 00309 operator+(const complex<_Tp>& __x) 00310 { return __x; } 00311 00312 template<typename _Tp> 00313 inline complex<_Tp> 00314 operator-(const complex<_Tp>& __x) 00315 { return complex<_Tp>(-__x.real(), -__x.imag()); } 00316 00317 template<typename _Tp> 00318 inline bool 00319 operator==(const complex<_Tp>& __x, const complex<_Tp>& __y) 00320 { return __x.real() == __y.real() && __x.imag() == __y.imag(); } 00321 00322 template<typename _Tp> 00323 inline bool 00324 operator==(const complex<_Tp>& __x, const _Tp& __y) 00325 { return __x.real() == __y && __x.imag() == _Tp(); } 00326 00327 template<typename _Tp> 00328 inline bool 00329 operator==(const _Tp& __x, const complex<_Tp>& __y) 00330 { return __x == __y.real() && _Tp() == __y.imag(); } 00331 00332 template<typename _Tp> 00333 inline bool 00334 operator!=(const complex<_Tp>& __x, const complex<_Tp>& __y) 00335 { return __x.real() != __y.real() || __x.imag() != __y.imag(); } 00336 00337 template<typename _Tp> 00338 inline bool 00339 operator!=(const complex<_Tp>& __x, const _Tp& __y) 00340 { return __x.real() != __y || __x.imag() != _Tp(); } 00341 00342 template<typename _Tp> 00343 inline bool 00344 operator!=(const _Tp& __x, const complex<_Tp>& __y) 00345 { return __x != __y.real() || _Tp() != __y.imag(); } 00346 00347 template<typename _Tp, typename _CharT, class _Traits> 00348 basic_istream<_CharT, _Traits>& 00349 operator>>(basic_istream<_CharT, _Traits>& __is, complex<_Tp>& __x) 00350 { 00351 _Tp __re_x, __im_x; 00352 _CharT __ch; 00353 __is >> __ch; 00354 if (__ch == '(') 00355 { 00356 __is >> __re_x >> __ch; 00357 if (__ch == ',') 00358 { 00359 __is >> __im_x >> __ch; 00360 if (__ch == ')') 00361 __x = complex<_Tp>(__re_x, __im_x); 00362 else 00363 __is.setstate(ios_base::failbit); 00364 } 00365 else if (__ch == ')') 00366 __x = complex<_Tp>(__re_x, _Tp(0)); 00367 else 00368 __is.setstate(ios_base::failbit); 00369 } 00370 else 00371 { 00372 __is.putback(__ch); 00373 __is >> __re_x; 00374 __x = complex<_Tp>(__re_x, _Tp(0)); 00375 } 00376 return __is; 00377 } 00378 00379 template<typename _Tp, typename _CharT, class _Traits> 00380 basic_ostream<_CharT, _Traits>& 00381 operator<<(basic_ostream<_CharT, _Traits>& __os, const complex<_Tp>& __x) 00382 { 00383 basic_ostringstream<_CharT, _Traits> __s; 00384 __s.flags(__os.flags()); 00385 __s.imbue(__os.getloc()); 00386 __s.precision(__os.precision()); 00387 __s << '(' << __x.real() << "," << __x.imag() << ')'; 00388 return __os << __s.str(); 00389 } 00390 00391 // Values 00392 template<typename _Tp> 00393 inline _Tp 00394 real(const complex<_Tp>& __z) 00395 { return __z.real(); } 00396 00397 template<typename _Tp> 00398 inline _Tp 00399 imag(const complex<_Tp>& __z) 00400 { return __z.imag(); } 00401 00402 template<typename _Tp> 00403 inline _Tp 00404 abs(const complex<_Tp>& __z) 00405 { 00406 _Tp __x = __z.real(); 00407 _Tp __y = __z.imag(); 00408 const _Tp __s = max(abs(__x), abs(__y)); 00409 if (__s == _Tp()) // well ... 00410 return __s; 00411 __x /= __s; 00412 __y /= __s; 00413 return __s * sqrt(__x * __x + __y * __y); 00414 } 00415 00416 template<typename _Tp> 00417 inline _Tp 00418 arg(const complex<_Tp>& __z) 00419 { return atan2(__z.imag(), __z.real()); } 00420 00421 // 26.2.7/5: norm(__z) returns the squared magintude of __z. 00422 // As defined, norm() is -not- a norm is the common mathematical 00423 // sens used in numerics. The helper class _Norm_helper<> tries to 00424 // distinguish between builtin floating point and the rest, so as 00425 // to deliver an answer as close as possible to the real value. 00426 template<bool> 00427 struct _Norm_helper 00428 { 00429 template<typename _Tp> 00430 static inline _Tp _S_do_it(const complex<_Tp>& __z) 00431 { 00432 const _Tp __x = __z.real(); 00433 const _Tp __y = __z.imag(); 00434 return __x * __x + __y * __y; 00435 } 00436 }; 00437 00438 template<> 00439 struct _Norm_helper<true> 00440 { 00441 template<typename _Tp> 00442 static inline _Tp _S_do_it(const complex<_Tp>& __z) 00443 { 00444 _Tp __res = abs(__z); 00445 return __res * __res; 00446 } 00447 }; 00448 00449 template<typename _Tp> 00450 inline _Tp 00451 norm(const complex<_Tp>& __z) 00452 { 00453 return _Norm_helper<__is_floating<_Tp>::_M_type>::_S_do_it(__z); 00454 } 00455 00456 template<typename _Tp> 00457 inline complex<_Tp> 00458 polar(const _Tp& __rho, const _Tp& __theta) 00459 { return complex<_Tp>(__rho * cos(__theta), __rho * sin(__theta)); } 00460 00461 template<typename _Tp> 00462 inline complex<_Tp> 00463 conj(const complex<_Tp>& __z) 00464 { return complex<_Tp>(__z.real(), -__z.imag()); } 00465 00466 // Transcendentals 00467 template<typename _Tp> 00468 inline complex<_Tp> 00469 cos(const complex<_Tp>& __z) 00470 { 00471 const _Tp __x = __z.real(); 00472 const _Tp __y = __z.imag(); 00473 return complex<_Tp>(cos(__x) * cosh(__y), -sin(__x) * sinh(__y)); 00474 } 00475 00476 template<typename _Tp> 00477 inline complex<_Tp> 00478 cosh(const complex<_Tp>& __z) 00479 { 00480 const _Tp __x = __z.real(); 00481 const _Tp __y = __z.imag(); 00482 return complex<_Tp>(cosh(__x) * cos(__y), sinh(__x) * sin(__y)); 00483 } 00484 00485 template<typename _Tp> 00486 inline complex<_Tp> 00487 exp(const complex<_Tp>& __z) 00488 { return polar(exp(__z.real()), __z.imag()); } 00489 00490 template<typename _Tp> 00491 inline complex<_Tp> 00492 log(const complex<_Tp>& __z) 00493 { return complex<_Tp>(log(abs(__z)), arg(__z)); } 00494 00495 template<typename _Tp> 00496 inline complex<_Tp> 00497 log10(const complex<_Tp>& __z) 00498 { return log(__z) / log(_Tp(10.0)); } 00499 00500 template<typename _Tp> 00501 inline complex<_Tp> 00502 sin(const complex<_Tp>& __z) 00503 { 00504 const _Tp __x = __z.real(); 00505 const _Tp __y = __z.imag(); 00506 return complex<_Tp>(sin(__x) * cosh(__y), cos(__x) * sinh(__y)); 00507 } 00508 00509 template<typename _Tp> 00510 inline complex<_Tp> 00511 sinh(const complex<_Tp>& __z) 00512 { 00513 const _Tp __x = __z.real(); 00514 const _Tp __y = __z.imag(); 00515 return complex<_Tp>(sinh(__x) * cos(__y), cosh(__x) * sin(__y)); 00516 } 00517 00518 template<typename _Tp> 00519 complex<_Tp> 00520 sqrt(const complex<_Tp>& __z) 00521 { 00522 _Tp __x = __z.real(); 00523 _Tp __y = __z.imag(); 00524 00525 if (__x == _Tp()) 00526 { 00527 _Tp __t = sqrt(abs(__y) / 2); 00528 return complex<_Tp>(__t, __y < _Tp() ? -__t : __t); 00529 } 00530 else 00531 { 00532 _Tp __t = sqrt(2 * (abs(__z) + abs(__x))); 00533 _Tp __u = __t / 2; 00534 return __x > _Tp() 00535 ? complex<_Tp>(__u, __y / __t) 00536 : complex<_Tp>(abs(__y) / __t, __y < _Tp() ? -__u : __u); 00537 } 00538 } 00539 00540 template<typename _Tp> 00541 inline complex<_Tp> 00542 tan(const complex<_Tp>& __z) 00543 { 00544 return sin(__z) / cos(__z); 00545 } 00546 00547 template<typename _Tp> 00548 inline complex<_Tp> 00549 tanh(const complex<_Tp>& __z) 00550 { 00551 return sinh(__z) / cosh(__z); 00552 } 00553 00554 template<typename _Tp> 00555 inline complex<_Tp> 00556 pow(const complex<_Tp>& __z, int __n) 00557 { 00558 return __pow_helper(__z, __n); 00559 } 00560 00561 template<typename _Tp> 00562 inline complex<_Tp> 00563 pow(const complex<_Tp>& __x, const _Tp& __y) 00564 { 00565 return exp(__y * log(__x)); 00566 } 00567 00568 template<typename _Tp> 00569 inline complex<_Tp> 00570 pow(const complex<_Tp>& __x, const complex<_Tp>& __y) 00571 { 00572 return exp(__y * log(__x)); 00573 } 00574 00575 template<typename _Tp> 00576 inline complex<_Tp> 00577 pow(const _Tp& __x, const complex<_Tp>& __y) 00578 { 00579 return exp(__y * log(__x)); 00580 } 00581 00582 // 26.2.3 complex specializations 00583 // complex<float> specialization 00584 template<> class complex<float> 00585 { 00586 public: 00587 typedef float value_type; 00588 00589 complex(float = 0.0f, float = 0.0f); 00590 #ifdef _GLIBCPP_BUGGY_COMPLEX 00591 complex(const complex& __z) : _M_value(__z._M_value) { } 00592 #endif 00593 explicit complex(const complex<double>&); 00594 explicit complex(const complex<long double>&); 00595 00596 float real() const; 00597 float imag() const; 00598 00599 complex<float>& operator=(float); 00600 complex<float>& operator+=(float); 00601 complex<float>& operator-=(float); 00602 complex<float>& operator*=(float); 00603 complex<float>& operator/=(float); 00604 00605 // Let's the compiler synthetize the copy and assignment 00606 // operator. It always does a pretty good job. 00607 // complex& operator= (const complex&); 00608 template<typename _Tp> 00609 complex<float>&operator=(const complex<_Tp>&); 00610 template<typename _Tp> 00611 complex<float>& operator+=(const complex<_Tp>&); 00612 template<class _Tp> 00613 complex<float>& operator-=(const complex<_Tp>&); 00614 template<class _Tp> 00615 complex<float>& operator*=(const complex<_Tp>&); 00616 template<class _Tp> 00617 complex<float>&operator/=(const complex<_Tp>&); 00618 00619 private: 00620 typedef __complex__ float _ComplexT; 00621 _ComplexT _M_value; 00622 00623 complex(_ComplexT __z) : _M_value(__z) { } 00624 00625 friend class complex<double>; 00626 friend class complex<long double>; 00627 }; 00628 00629 inline float 00630 complex<float>::real() const 00631 { return __real__ _M_value; } 00632 00633 inline float 00634 complex<float>::imag() const 00635 { return __imag__ _M_value; } 00636 00637 inline 00638 complex<float>::complex(float r, float i) 00639 { 00640 __real__ _M_value = r; 00641 __imag__ _M_value = i; 00642 } 00643 00644 inline complex<float>& 00645 complex<float>::operator=(float __f) 00646 { 00647 __real__ _M_value = __f; 00648 __imag__ _M_value = 0.0f; 00649 return *this; 00650 } 00651 00652 inline complex<float>& 00653 complex<float>::operator+=(float __f) 00654 { 00655 __real__ _M_value += __f; 00656 return *this; 00657 } 00658 00659 inline complex<float>& 00660 complex<float>::operator-=(float __f) 00661 { 00662 __real__ _M_value -= __f; 00663 return *this; 00664 } 00665 00666 inline complex<float>& 00667 complex<float>::operator*=(float __f) 00668 { 00669 _M_value *= __f; 00670 return *this; 00671 } 00672 00673 inline complex<float>& 00674 complex<float>::operator/=(float __f) 00675 { 00676 _M_value /= __f; 00677 return *this; 00678 } 00679 00680 template<typename _Tp> 00681 inline complex<float>& 00682 complex<float>::operator=(const complex<_Tp>& __z) 00683 { 00684 __real__ _M_value = __z.real(); 00685 __imag__ _M_value = __z.imag(); 00686 return *this; 00687 } 00688 00689 template<typename _Tp> 00690 inline complex<float>& 00691 complex<float>::operator+=(const complex<_Tp>& __z) 00692 { 00693 __real__ _M_value += __z.real(); 00694 __imag__ _M_value += __z.imag(); 00695 return *this; 00696 } 00697 00698 template<typename _Tp> 00699 inline complex<float>& 00700 complex<float>::operator-=(const complex<_Tp>& __z) 00701 { 00702 __real__ _M_value -= __z.real(); 00703 __imag__ _M_value -= __z.imag(); 00704 return *this; 00705 } 00706 00707 template<typename _Tp> 00708 inline complex<float>& 00709 complex<float>::operator*=(const complex<_Tp>& __z) 00710 { 00711 _ComplexT __t; 00712 __real__ __t = __z.real(); 00713 __imag__ __t = __z.imag(); 00714 _M_value *= __t; 00715 return *this; 00716 } 00717 00718 template<typename _Tp> 00719 inline complex<float>& 00720 complex<float>::operator/=(const complex<_Tp>& __z) 00721 { 00722 _ComplexT __t; 00723 __real__ __t = __z.real(); 00724 __imag__ __t = __z.imag(); 00725 _M_value /= __t; 00726 return *this; 00727 } 00728 00729 // 26.2.3 complex specializations 00730 // complex<double> specialization 00731 template<> class complex<double> 00732 { 00733 public: 00734 typedef double value_type; 00735 00736 complex(double =0.0, double =0.0); 00737 #ifdef _GLIBCPP_BUGGY_COMPLEX 00738 complex(const complex& __z) : _M_value(__z._M_value) { } 00739 #endif 00740 complex(const complex<float>&); 00741 explicit complex(const complex<long double>&); 00742 00743 double real() const; 00744 double imag() const; 00745 00746 complex<double>& operator=(double); 00747 complex<double>& operator+=(double); 00748 complex<double>& operator-=(double); 00749 complex<double>& operator*=(double); 00750 complex<double>& operator/=(double); 00751 00752 // The compiler will synthetize this, efficiently. 00753 // complex& operator= (const complex&); 00754 template<typename _Tp> 00755 complex<double>& operator=(const complex<_Tp>&); 00756 template<typename _Tp> 00757 complex<double>& operator+=(const complex<_Tp>&); 00758 template<typename _Tp> 00759 complex<double>& operator-=(const complex<_Tp>&); 00760 template<typename _Tp> 00761 complex<double>& operator*=(const complex<_Tp>&); 00762 template<typename _Tp> 00763 complex<double>& operator/=(const complex<_Tp>&); 00764 00765 private: 00766 typedef __complex__ double _ComplexT; 00767 _ComplexT _M_value; 00768 00769 complex(_ComplexT __z) : _M_value(__z) { } 00770 00771 friend class complex<float>; 00772 friend class complex<long double>; 00773 }; 00774 00775 inline double 00776 complex<double>::real() const 00777 { return __real__ _M_value; } 00778 00779 inline double 00780 complex<double>::imag() const 00781 { return __imag__ _M_value; } 00782 00783 inline 00784 complex<double>::complex(double __r, double __i) 00785 { 00786 __real__ _M_value = __r; 00787 __imag__ _M_value = __i; 00788 } 00789 00790 inline complex<double>& 00791 complex<double>::operator=(double __d) 00792 { 00793 __real__ _M_value = __d; 00794 __imag__ _M_value = 0.0; 00795 return *this; 00796 } 00797 00798 inline complex<double>& 00799 complex<double>::operator+=(double __d) 00800 { 00801 __real__ _M_value += __d; 00802 return *this; 00803 } 00804 00805 inline complex<double>& 00806 complex<double>::operator-=(double __d) 00807 { 00808 __real__ _M_value -= __d; 00809 return *this; 00810 } 00811 00812 inline complex<double>& 00813 complex<double>::operator*=(double __d) 00814 { 00815 _M_value *= __d; 00816 return *this; 00817 } 00818 00819 inline complex<double>& 00820 complex<double>::operator/=(double __d) 00821 { 00822 _M_value /= __d; 00823 return *this; 00824 } 00825 00826 template<typename _Tp> 00827 inline complex<double>& 00828 complex<double>::operator=(const complex<_Tp>& __z) 00829 { 00830 __real__ _M_value = __z.real(); 00831 __imag__ _M_value = __z.imag(); 00832 return *this; 00833 } 00834 00835 template<typename _Tp> 00836 inline complex<double>& 00837 complex<double>::operator+=(const complex<_Tp>& __z) 00838 { 00839 __real__ _M_value += __z.real(); 00840 __imag__ _M_value += __z.imag(); 00841 return *this; 00842 } 00843 00844 template<typename _Tp> 00845 inline complex<double>& 00846 complex<double>::operator-=(const complex<_Tp>& __z) 00847 { 00848 __real__ _M_value -= __z.real(); 00849 __imag__ _M_value -= __z.imag(); 00850 return *this; 00851 } 00852 00853 template<typename _Tp> 00854 inline complex<double>& 00855 complex<double>::operator*=(const complex<_Tp>& __z) 00856 { 00857 _ComplexT __t; 00858 __real__ __t = __z.real(); 00859 __imag__ __t = __z.imag(); 00860 _M_value *= __t; 00861 return *this; 00862 } 00863 00864 template<typename _Tp> 00865 inline complex<double>& 00866 complex<double>::operator/=(const complex<_Tp>& __z) 00867 { 00868 _ComplexT __t; 00869 __real__ __t = __z.real(); 00870 __imag__ __t = __z.imag(); 00871 _M_value /= __t; 00872 return *this; 00873 } 00874 00875 // 26.2.3 complex specializations 00876 // complex<long double> specialization 00877 template<> class complex<long double> 00878 { 00879 public: 00880 typedef long double value_type; 00881 00882 complex(long double = 0.0L, long double = 0.0L); 00883 #ifdef _GLIBCPP_BUGGY_COMPLEX 00884 complex(const complex& __z) : _M_value(__z._M_value) { } 00885 #endif 00886 complex(const complex<float>&); 00887 complex(const complex<double>&); 00888 00889 long double real() const; 00890 long double imag() const; 00891 00892 complex<long double>& operator= (long double); 00893 complex<long double>& operator+= (long double); 00894 complex<long double>& operator-= (long double); 00895 complex<long double>& operator*= (long double); 00896 complex<long double>& operator/= (long double); 00897 00898 // The compiler knows how to do this efficiently 00899 // complex& operator= (const complex&); 00900 template<typename _Tp> 00901 complex<long double>& operator=(const complex<_Tp>&); 00902 template<typename _Tp> 00903 complex<long double>& operator+=(const complex<_Tp>&); 00904 template<typename _Tp> 00905 complex<long double>& operator-=(const complex<_Tp>&); 00906 template<typename _Tp> 00907 complex<long double>& operator*=(const complex<_Tp>&); 00908 template<typename _Tp> 00909 complex<long double>& operator/=(const complex<_Tp>&); 00910 00911 private: 00912 typedef __complex__ long double _ComplexT; 00913 _ComplexT _M_value; 00914 00915 complex(_ComplexT __z) : _M_value(__z) { } 00916 00917 friend class complex<float>; 00918 friend class complex<double>; 00919 }; 00920 00921 inline 00922 complex<long double>::complex(long double __r, long double __i) 00923 { 00924 __real__ _M_value = __r; 00925 __imag__ _M_value = __i; 00926 } 00927 00928 inline long double 00929 complex<long double>::real() const 00930 { return __real__ _M_value; } 00931 00932 inline long double 00933 complex<long double>::imag() const 00934 { return __imag__ _M_value; } 00935 00936 inline complex<long double>& 00937 complex<long double>::operator=(long double __r) 00938 { 00939 __real__ _M_value = __r; 00940 __imag__ _M_value = 0.0L; 00941 return *this; 00942 } 00943 00944 inline complex<long double>& 00945 complex<long double>::operator+=(long double __r) 00946 { 00947 __real__ _M_value += __r; 00948 return *this; 00949 } 00950 00951 inline complex<long double>& 00952 complex<long double>::operator-=(long double __r) 00953 { 00954 __real__ _M_value -= __r; 00955 return *this; 00956 } 00957 00958 inline complex<long double>& 00959 complex<long double>::operator*=(long double __r) 00960 { 00961 _M_value *= __r; 00962 return *this; 00963 } 00964 00965 inline complex<long double>& 00966 complex<long double>::operator/=(long double __r) 00967 { 00968 _M_value /= __r; 00969 return *this; 00970 } 00971 00972 template<typename _Tp> 00973 inline complex<long double>& 00974 complex<long double>::operator=(const complex<_Tp>& __z) 00975 { 00976 __real__ _M_value = __z.real(); 00977 __imag__ _M_value = __z.imag(); 00978 return *this; 00979 } 00980 00981 template<typename _Tp> 00982 inline complex<long double>& 00983 complex<long double>::operator+=(const complex<_Tp>& __z) 00984 { 00985 __real__ _M_value += __z.real(); 00986 __imag__ _M_value += __z.imag(); 00987 return *this; 00988 } 00989 00990 template<typename _Tp> 00991 inline complex<long double>& 00992 complex<long double>::operator-=(const complex<_Tp>& __z) 00993 { 00994 __real__ _M_value -= __z.real(); 00995 __imag__ _M_value -= __z.imag(); 00996 return *this; 00997 } 00998 00999 template<typename _Tp> 01000 inline complex<long double>& 01001 complex<long double>::operator*=(const complex<_Tp>& __z) 01002 { 01003 _ComplexT __t; 01004 __real__ __t = __z.real(); 01005 __imag__ __t = __z.imag(); 01006 _M_value *= __t; 01007 return *this; 01008 } 01009 01010 template<typename _Tp> 01011 inline complex<long double>& 01012 complex<long double>::operator/=(const complex<_Tp>& __z) 01013 { 01014 _ComplexT __t; 01015 __real__ __t = __z.real(); 01016 __imag__ __t = __z.imag(); 01017 _M_value /= __t; 01018 return *this; 01019 } 01020 01021 // These bits have to be at the end of this file, so that the 01022 // specializations have all been defined. 01023 // ??? No, they have to be there because of compiler limitation at 01024 // inlining. It suffices that class specializations be defined. 01025 inline 01026 complex<float>::complex(const complex<double>& __z) 01027 : _M_value(_ComplexT(__z._M_value)) { } 01028 01029 inline 01030 complex<float>::complex(const complex<long double>& __z) 01031 : _M_value(_ComplexT(__z._M_value)) { } 01032 01033 inline 01034 complex<double>::complex(const complex<float>& __z) 01035 : _M_value(_ComplexT(__z._M_value)) { } 01036 01037 inline 01038 complex<double>::complex(const complex<long double>& __z) 01039 { 01040 __real__ _M_value = __z.real(); 01041 __imag__ _M_value = __z.imag(); 01042 } 01043 01044 inline 01045 complex<long double>::complex(const complex<float>& __z) 01046 : _M_value(_ComplexT(__z._M_value)) { } 01047 01048 inline 01049 complex<long double>::complex(const complex<double>& __z) 01050 : _M_value(_ComplexT(__z._M_value)) { } 01051 } // namespace std 01052 01053 #endif /* _CPP_COMPLEX */ Generated on Mon Apr 8 03:11:33 2002 for libstdc++-v3 Source by ![]() |