complex

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

Generated on Wed Sep 29 13:54:47 2004 for libstdc++-v3 Source by doxygen 1.3.7