1093 lines
27 KiB
Plaintext
1093 lines
27 KiB
Plaintext
// complex standard header
|
|
#pragma once
|
|
#ifndef _COMPLEX_
|
|
#define _COMPLEX_
|
|
#include <ymath.h>
|
|
#include <cmath>
|
|
#include <sstream>
|
|
|
|
#pragma pack(push,8)
|
|
#pragma warning(push,3)
|
|
|
|
#pragma warning(disable: 4244)
|
|
_STD_BEGIN
|
|
|
|
#define __STD_COMPLEX /* signal presence of complex classes */
|
|
|
|
// TEMPLATE CLASS _Ctraits
|
|
template<class _Ty>
|
|
class _Ctraits
|
|
{ // complex traits for _Ty
|
|
public:
|
|
static _Ty __cdecl _Cosh(_Ty _Left, _Ty _Right)
|
|
{ // return cosh(_Left) * _Right
|
|
return (::_Cosh((double)_Left, (double)_Right));
|
|
}
|
|
|
|
static short __cdecl _Exp(_Ty *_Pleft, _Ty _Right, short _Exponent)
|
|
{ // compute exp(*_Pleft) * _Right * 2 ^ _Exponent
|
|
double _Tmp = (double)*_Pleft;
|
|
short _Ans = ::_Exp(&_Tmp, (double)_Right, _Exponent);
|
|
*_Pleft = (_Ty)_Tmp;
|
|
return (_Ans);
|
|
}
|
|
|
|
static _Ty __cdecl _Infv(_Ty)
|
|
{ // return infinity
|
|
return (::_Inf._Double);
|
|
}
|
|
|
|
static bool __cdecl _Isinf(_Ty _Left)
|
|
{ // test for infinity
|
|
double _Tmp = (double)_Left;
|
|
return (::_Dtest(&_Tmp) == _INFCODE);
|
|
}
|
|
|
|
static bool __cdecl _Isnan(_Ty _Left)
|
|
{ // test for NaN
|
|
double _Tmp = (double)_Left;
|
|
return (::_Dtest(&_Tmp) == _NANCODE);
|
|
}
|
|
|
|
static _Ty __cdecl _Nanv(_Ty)
|
|
{ // return NaN
|
|
return (::_Nan._Double);
|
|
}
|
|
|
|
static _Ty __cdecl _Sinh(_Ty _Left, _Ty _Right)
|
|
{ // return sinh(_Left) * _Right
|
|
return (::_Sinh((double)_Left, (double)_Right));
|
|
}
|
|
|
|
static _Ty __cdecl atan2(_Ty _Yval, _Ty _Xval)
|
|
{ // return atan(_Yval / _Xval)
|
|
return (::atan2((double)_Yval, (double)_Xval));
|
|
}
|
|
|
|
static _Ty __cdecl cos(_Ty _Left)
|
|
{ // return cos(_Left)
|
|
return (::cos((double)_Left));
|
|
}
|
|
|
|
static _Ty __cdecl exp(_Ty _Left)
|
|
{ // return exp(_Left)
|
|
return (::exp((double)_Left));
|
|
}
|
|
|
|
static _Ty __cdecl ldexp(_Ty _Left, int _Exponent)
|
|
{ // return _Left * 2 ^ _Exponent
|
|
return (::ldexp((double)_Left, _Exponent));
|
|
}
|
|
|
|
static _Ty __cdecl log(_Ty _Left)
|
|
{ // return log(_Left)
|
|
return (::log((double)_Left));
|
|
}
|
|
|
|
static _Ty __cdecl pow(_Ty _Left, _Ty _Right)
|
|
{ // return _Left ^ _Right
|
|
return (::pow((double)_Left, (double)_Right));
|
|
}
|
|
|
|
static _Ty __cdecl sin(_Ty _Left)
|
|
{ // return sin(_Left)
|
|
return (::sin((double)_Left));
|
|
}
|
|
|
|
static _Ty __cdecl sqrt(_Ty _Left)
|
|
{ // return sqrt(_Left)
|
|
return (::sqrt((double)_Left));
|
|
}
|
|
|
|
static _Ty __cdecl tan(_Ty _Left)
|
|
{ // return tan(_Left)
|
|
return (::tan((double)_Left));
|
|
}
|
|
};
|
|
|
|
// CLASS _Ctraits<long double>
|
|
template<> class _CRTIMP2 _Ctraits<long double>
|
|
{ // complex traits for long double
|
|
public:
|
|
typedef long double _Ty;
|
|
|
|
static _Ty __cdecl _Cosh(_Ty _Left, _Ty _Right)
|
|
{ // return cosh(_Left) * _Right
|
|
return (::_LCosh(_Left, _Right));
|
|
}
|
|
|
|
static short __cdecl _Exp(_Ty *_Pleft, _Ty _Right, short _Exponent)
|
|
{ // compute exp(*_Pleft) * _Right * 2 ^ _Exponent
|
|
return (::_LExp(_Pleft, _Right, _Exponent));
|
|
}
|
|
|
|
static _Ty __cdecl _Infv(_Ty)
|
|
{ // return infinity
|
|
return (::_LInf._Long_double);
|
|
}
|
|
|
|
static bool __cdecl _Isinf(_Ty _Left)
|
|
{ // test for infinity
|
|
return (::_LDtest(&_Left) == _INFCODE);
|
|
}
|
|
|
|
static bool __cdecl _Isnan(_Ty _Left)
|
|
{ // test for NaN
|
|
return (::_LDtest(&_Left) == _NANCODE);
|
|
}
|
|
|
|
static _Ty __cdecl _Nanv(_Ty)
|
|
{ // return NaN
|
|
return (::_LNan._Long_double);
|
|
}
|
|
|
|
static _Ty __cdecl _Sinh(_Ty _Left, _Ty _Right)
|
|
{ // return sinh(_Left) * _Right
|
|
return (::_LSinh(_Left, _Right));
|
|
}
|
|
|
|
static _Ty __cdecl atan2(_Ty _Yval, _Ty _Xval)
|
|
{ // return atan(_Yval / _Xval)
|
|
return (::atan2l(_Yval, _Xval));
|
|
}
|
|
|
|
static _Ty __cdecl cos(_Ty _Left)
|
|
{ // return cos(_Left)
|
|
return (::cosl(_Left));
|
|
}
|
|
|
|
static _Ty __cdecl exp(_Ty _Left)
|
|
{ // return exp(_Left)
|
|
return (::expl(_Left));
|
|
}
|
|
|
|
static _Ty __cdecl ldexp(_Ty _Left, int _Exponent)
|
|
{ // return _Left * 2 ^ _Exponent
|
|
return (::ldexpl(_Left, _Exponent));
|
|
}
|
|
|
|
static _Ty __cdecl log(_Ty _Left)
|
|
{ // return log(_Left)
|
|
return (::logl(_Left));
|
|
}
|
|
|
|
static _Ty __cdecl pow(_Ty _Left, _Ty _Right)
|
|
{ // return _Left ^ _Right
|
|
return (::powl(_Left, _Right));
|
|
}
|
|
|
|
static _Ty __cdecl sin(_Ty _Left)
|
|
{ // return sin(_Left)
|
|
return (::sinl(_Left));
|
|
}
|
|
|
|
static _Ty __cdecl sqrt(_Ty _Left)
|
|
{ // return sqrt(_Left)
|
|
return (::sqrtl(_Left));
|
|
}
|
|
|
|
static _Ty __cdecl tan(_Ty _Left)
|
|
{ // return tan(_Left)
|
|
return (::tanl(_Left));
|
|
}
|
|
};
|
|
|
|
// CLASS _Ctraits<double>
|
|
template<> class _CRTIMP2 _Ctraits<double>
|
|
{ // complex traits for double
|
|
public:
|
|
typedef double _Ty;
|
|
|
|
static _Ty __cdecl _Cosh(_Ty _Left, _Ty _Right)
|
|
{ // return cosh(_Left) * _Right
|
|
return (::_Cosh(_Left, _Right));
|
|
}
|
|
|
|
static short __cdecl _Exp(_Ty *_Pleft, _Ty _Right, short _Exponent)
|
|
{ // compute exp(*_Pleft) * _Right * 2 ^ _Exponent
|
|
return (::_Exp(_Pleft, _Right, _Exponent));
|
|
}
|
|
|
|
static _Ty __cdecl _Infv(_Ty)
|
|
{ // return infinity
|
|
return (::_Inf._Double);
|
|
}
|
|
|
|
static bool __cdecl _Isinf(_Ty _Left)
|
|
{ // test for infinity
|
|
return (::_Dtest(&_Left) == _INFCODE);
|
|
}
|
|
|
|
static bool __cdecl _Isnan(_Ty _Left)
|
|
{ // test for NaN
|
|
return (::_Dtest(&_Left) == _NANCODE);
|
|
}
|
|
|
|
static _Ty __cdecl _Nanv(_Ty)
|
|
{ // return NaN
|
|
return (::_Nan._Double);
|
|
}
|
|
|
|
static _Ty __cdecl _Sinh(_Ty _Left, _Ty _Right)
|
|
{ // return sinh(_Left) * _Right
|
|
return (::_Sinh(_Left, _Right));
|
|
}
|
|
|
|
static _Ty __cdecl atan2(_Ty _Yval, _Ty _Xval)
|
|
{ // return atan(_Yval / _Xval)
|
|
return (::atan2(_Yval, _Xval));
|
|
}
|
|
|
|
static _Ty __cdecl cos(_Ty _Left)
|
|
{ // return cos(_Left)
|
|
return (::cos(_Left));
|
|
}
|
|
|
|
static _Ty __cdecl exp(_Ty _Left)
|
|
{ // return exp(_Left)
|
|
return (::exp(_Left));
|
|
}
|
|
|
|
static _Ty __cdecl ldexp(_Ty _Left, int _Exponent)
|
|
{ // return _Left * 2 ^ _Exponent
|
|
return (::ldexp(_Left, _Exponent));
|
|
}
|
|
|
|
static _Ty __cdecl log(_Ty _Left)
|
|
{ // return log(_Left)
|
|
return (::log(_Left));
|
|
}
|
|
|
|
static _Ty __cdecl pow(_Ty _Left, _Ty _Right)
|
|
{ // return _Left ^ _Right
|
|
return (::pow(_Left, _Right));
|
|
}
|
|
|
|
static _Ty __cdecl sin(_Ty _Left)
|
|
{ // return sin(_Left)
|
|
return (::sin(_Left));
|
|
}
|
|
|
|
static _Ty __cdecl sqrt(_Ty _Left)
|
|
{ // return sqrt(_Left)
|
|
return (::sqrt(_Left));
|
|
}
|
|
|
|
static _Ty __cdecl tan(_Ty _Left)
|
|
{ // return tan(_Left)
|
|
return (::tan(_Left));
|
|
}
|
|
};
|
|
|
|
// CLASS _Ctraits<float>
|
|
template<> class _CRTIMP2 _Ctraits<float>
|
|
{ // complex traits for float
|
|
public:
|
|
typedef float _Ty;
|
|
|
|
static _Ty __cdecl _Cosh(_Ty _Left, _Ty _Right)
|
|
{ // return cosh(_Left) * _Right
|
|
return (::_FCosh(_Left, _Right));
|
|
}
|
|
|
|
static short __cdecl _Exp(_Ty *_Pleft, _Ty _Right, short _Exponent)
|
|
{ // compute exp(*_Pleft) * _Right * 2 ^ _Exponent
|
|
return (::_FExp(_Pleft, _Right, _Exponent));
|
|
}
|
|
|
|
static _Ty __cdecl _Infv(_Ty)
|
|
{ // return infinity
|
|
return (::_FInf._Float);
|
|
}
|
|
|
|
static bool __cdecl _Isinf(_Ty _Left)
|
|
{ // test for infinity
|
|
return (::_FDtest(&_Left) == _INFCODE);
|
|
}
|
|
|
|
static bool __cdecl _Isnan(_Ty _Left)
|
|
{ // test for NaN
|
|
return (::_FDtest(&_Left) == _NANCODE);
|
|
}
|
|
|
|
static _Ty __cdecl _Nanv(_Ty)
|
|
{ // return NaN
|
|
return (::_FNan._Float);
|
|
}
|
|
|
|
static _Ty __cdecl _Sinh(_Ty _Left, _Ty _Right)
|
|
{ // return sinh(_Left) * _Right
|
|
return (::_FSinh(_Left, _Right));
|
|
}
|
|
|
|
static _Ty __cdecl atan2(_Ty _Yval, _Ty _Xval)
|
|
{ // return atan(_Yval / _Xval)
|
|
return (::atan2f(_Yval, _Xval));
|
|
}
|
|
|
|
static _Ty __cdecl cos(_Ty _Left)
|
|
{ // return cos(_Left)
|
|
return (::cosf(_Left));
|
|
}
|
|
|
|
static _Ty __cdecl exp(_Ty _Left)
|
|
{ // return exp(_Left)
|
|
return (::expf(_Left));
|
|
}
|
|
|
|
static _Ty __cdecl ldexp(_Ty _Left, int _Exponent)
|
|
{ // return _Left * 2 ^ _Exponent
|
|
return (::ldexpf(_Left, _Exponent));
|
|
}
|
|
|
|
static _Ty __cdecl log(_Ty _Left)
|
|
{ // return log(_Left)
|
|
return (::logf(_Left));
|
|
}
|
|
|
|
static _Ty __cdecl pow(_Ty _Left, _Ty _Right)
|
|
{ // return _Left ^ _Right
|
|
return (::powf(_Left, _Right));
|
|
}
|
|
|
|
static _Ty __cdecl sin(_Ty _Left)
|
|
{ // return sin(_Left)
|
|
return (::sinf(_Left));
|
|
}
|
|
|
|
static _Ty __cdecl sqrt(_Ty _Left)
|
|
{ // return sqrt(_Left)
|
|
return (::sqrtf(_Left));
|
|
}
|
|
|
|
static _Ty __cdecl tan(_Ty _Left)
|
|
{ // return tan(_Left)
|
|
return (::tanf(_Left));
|
|
}
|
|
};
|
|
|
|
template<class _Ty>
|
|
class complex;
|
|
template<> class _CRTIMP2 complex<float>;
|
|
template<> class _CRTIMP2 complex<double>;
|
|
template<> class _CRTIMP2 complex<long double>;
|
|
|
|
// TEMPLATE CLASS _Complex_base
|
|
template<class _Ty>
|
|
class _Complex_base
|
|
{ // base for all complex types
|
|
public:
|
|
typedef _Ctraits<_Ty> _Myctraits;
|
|
typedef _Complex_base<_Ty> _Myt;
|
|
typedef _Ty value_type;
|
|
|
|
_Complex_base(const _Ty& _Realval, const _Ty& _Imagval)
|
|
: _Real(_Realval), _Imag(_Imagval)
|
|
{ // construct from components of same type
|
|
}
|
|
|
|
_Ty real(const _Ty& _Right)
|
|
{ // set real component
|
|
return (_Real = _Right);
|
|
}
|
|
|
|
_Ty imag(const _Ty& _Right)
|
|
{ // set imaginary component
|
|
return (_Imag = _Right);
|
|
}
|
|
|
|
_Ty real() const
|
|
{ // return real component
|
|
return (_Real);
|
|
}
|
|
|
|
_Ty imag() const
|
|
{ // return imaginary component
|
|
return (_Imag);
|
|
}
|
|
|
|
protected:
|
|
template<class _Other> inline
|
|
void _Add(const complex<_Other>& _Right)
|
|
{ // add other complex
|
|
_Real = _Real + (_Ty)_Right.real();
|
|
_Imag = _Imag + (_Ty)_Right.imag();
|
|
}
|
|
|
|
template<class _Other> inline
|
|
void _Sub(const complex<_Other>& _Right)
|
|
{ // subtract other complex
|
|
_Real = _Real - (_Ty)_Right.real();
|
|
_Imag = _Imag - (_Ty)_Right.imag();
|
|
}
|
|
|
|
template<class _Other> inline
|
|
void _Mul(const complex<_Other>& _Right)
|
|
{ // multiply by other complex
|
|
_Ty _Rightreal = (_Ty)_Right.real();
|
|
_Ty _Rightimag = (_Ty)_Right.imag();
|
|
|
|
_Ty _Tmp = _Real * _Rightreal - _Imag * _Rightimag;
|
|
_Imag = _Real * _Rightimag + _Imag * _Rightreal;
|
|
_Real = _Tmp;
|
|
}
|
|
|
|
template<class _Other> inline
|
|
void _Div(const complex<_Other>& _Right)
|
|
{ // divide by other complex
|
|
typedef _Ctraits<_Ty> _Myctraits;
|
|
_Ty _Rightreal = (_Ty)_Right.real();
|
|
_Ty _Rightimag = (_Ty)_Right.imag();
|
|
|
|
if (_Myctraits::_Isnan(_Rightreal) || _Myctraits::_Isnan(_Rightimag))
|
|
{ // set NaN result
|
|
_Real = _Myctraits::_Nanv(_Rightreal);
|
|
_Imag = _Real;
|
|
}
|
|
else if ((_Rightimag < 0 ? -_Rightimag : +_Rightimag)
|
|
< (_Rightreal < 0 ? -_Rightreal : +_Rightreal))
|
|
{ // |_Right.imag()| < |_Right.real()|
|
|
_Ty _Wr = _Rightimag / _Rightreal;
|
|
_Ty _Wd = _Rightreal + _Wr * _Rightimag;
|
|
|
|
if (_Myctraits::_Isnan(_Wd) || _Wd == 0)
|
|
{ // set NaN result
|
|
_Real = _Myctraits::_Nanv(_Rightreal);
|
|
_Imag = _Real;
|
|
}
|
|
else
|
|
{ // compute representable result
|
|
_Ty _Tmp = (_Real + _Imag * _Wr) / _Wd;
|
|
_Imag = (_Imag - _Real * _Wr) / _Wd;
|
|
_Real = _Tmp;
|
|
}
|
|
}
|
|
else if (_Rightimag == 0)
|
|
{ // set NaN result
|
|
_Real = _Myctraits::_Nanv(_Rightreal);
|
|
_Imag = _Real;
|
|
}
|
|
else
|
|
{ // 0 < |_Right.real()| <= |_Right.imag()|
|
|
_Ty _Wr = _Rightreal / _Rightimag;
|
|
_Ty _Wd = _Rightimag + _Wr * _Rightreal;
|
|
|
|
if (_Myctraits::_Isnan(_Wd) || _Wd == 0)
|
|
{ // set NaN result
|
|
_Real = _Myctraits::_Nanv(_Rightreal);
|
|
_Imag = _Real;
|
|
}
|
|
else
|
|
{ // compute representable result
|
|
_Ty _Tmp = (_Real * _Wr + _Imag) / _Wd;
|
|
_Imag = (_Imag * _Wr - _Real) / _Wd;
|
|
_Real = _Tmp;
|
|
}
|
|
}
|
|
}
|
|
|
|
_Ty _Real; // the real component
|
|
_Ty _Imag; // the imaginary component
|
|
};
|
|
|
|
// CLASS complex<float>
|
|
template<> class _CRTIMP2 complex<float>
|
|
: public _Complex_base<float>
|
|
{ // complex with float components
|
|
public:
|
|
typedef float _Ty;
|
|
typedef complex<_Ty> _Myt;
|
|
|
|
explicit complex(const complex<double>&); // defined below
|
|
|
|
explicit complex(const complex<long double>&); // defined below
|
|
|
|
complex(const _Ty& _Realval = 0, const _Ty& _Imagval = 0)
|
|
: _Complex_base<_Ty>(_Realval, _Imagval)
|
|
{ // construct from float components
|
|
}
|
|
|
|
complex<_Ty>& operator=(const _Ty& _Right)
|
|
{ // assign real
|
|
_Real = _Right;
|
|
_Imag = 0;
|
|
return (*this);
|
|
}
|
|
|
|
_Myt& operator+=(const _Ty& _Right)
|
|
{ // add real
|
|
_Real = _Real + _Right;
|
|
return (*this);
|
|
}
|
|
|
|
_Myt& operator-=(const _Ty& _Right)
|
|
{ // subtract real
|
|
_Real = _Real - _Right;
|
|
return (*this);
|
|
}
|
|
|
|
_Myt& operator*=(const _Ty& _Right)
|
|
{ // multiply by real
|
|
_Real = _Real * _Right;
|
|
_Imag = _Imag * _Right;
|
|
return (*this);
|
|
}
|
|
|
|
_Myt& operator/=(const _Ty& _Right)
|
|
{ // divide by real
|
|
_Real = _Real / _Right;
|
|
_Imag = _Imag / _Right;
|
|
return (*this);
|
|
}
|
|
|
|
_Myt& operator+=(const _Myt& _Right)
|
|
{ // add other complex
|
|
_Add(_Right);
|
|
return (*this);
|
|
}
|
|
|
|
_Myt& operator-=(const _Myt& _Right)
|
|
{ // subtract other complex
|
|
_Sub(_Right);
|
|
return (*this);
|
|
}
|
|
|
|
_Myt& operator*=(const _Myt& _Right)
|
|
{ // multiply by other complex
|
|
_Mul(_Right);
|
|
return (*this);
|
|
}
|
|
|
|
_Myt& operator/=(const _Myt& _Right)
|
|
{ // divide by other complex
|
|
_Div(_Right);
|
|
return (*this);
|
|
}
|
|
|
|
template<class _Other> inline
|
|
_Myt& operator+=(const complex<_Other>& _Right)
|
|
{ // add other complex
|
|
_Add(_Right);
|
|
return (*this);
|
|
}
|
|
|
|
template<class _Other> inline
|
|
_Myt& operator-=(const complex<_Other>& _Right)
|
|
{ // subtract other complex
|
|
_Sub(_Right);
|
|
return (*this);
|
|
}
|
|
|
|
template<class _Other> inline
|
|
_Myt& operator*=(const complex<_Other>& _Right)
|
|
{ // multiply by other complex
|
|
_Mul(_Right);
|
|
return (*this);
|
|
}
|
|
|
|
template<class _Other> inline
|
|
_Myt& operator/=(const complex<_Other>& _Right)
|
|
{ // divide by other complex
|
|
_Div(_Right);
|
|
return (*this);
|
|
}
|
|
};
|
|
|
|
// CLASS complex<double>
|
|
template<> class _CRTIMP2 complex<double>
|
|
: public _Complex_base<double>
|
|
{ // complex with double components
|
|
public:
|
|
typedef double _Ty;
|
|
typedef complex<_Ty> _Myt;
|
|
|
|
complex(const complex<float>&); // defined below
|
|
|
|
explicit complex(const complex<long double>&); // defined below
|
|
|
|
complex(const _Ty& _Realval = 0, const _Ty& _Imagval = 0)
|
|
: _Complex_base<_Ty>(_Realval, _Imagval)
|
|
{ // construct from double components
|
|
}
|
|
|
|
complex<_Ty>& operator=(const _Ty& _Right)
|
|
{ // assign real
|
|
_Real = _Right;
|
|
_Imag = 0;
|
|
return (*this);
|
|
}
|
|
|
|
_Myt& operator+=(const _Ty& _Right)
|
|
{ // add real
|
|
_Real = _Real + _Right;
|
|
return (*this);
|
|
}
|
|
|
|
_Myt& operator-=(const _Ty& _Right)
|
|
{ // subtract real
|
|
_Real = _Real - _Right;
|
|
return (*this);
|
|
}
|
|
|
|
_Myt& operator*=(const _Ty& _Right)
|
|
{ // multiply by real
|
|
_Real = _Real * _Right;
|
|
_Imag = _Imag * _Right;
|
|
return (*this);
|
|
}
|
|
|
|
_Myt& operator/=(const _Ty& _Right)
|
|
{ // divide by real
|
|
_Real = _Real / _Right;
|
|
_Imag = _Imag / _Right;
|
|
return (*this);
|
|
}
|
|
|
|
_Myt& operator+=(const _Myt& _Right)
|
|
{ // add other complex
|
|
_Add(_Right);
|
|
return (*this);
|
|
}
|
|
|
|
_Myt& operator-=(const _Myt& _Right)
|
|
{ // subtract other complex
|
|
_Sub(_Right);
|
|
return (*this);
|
|
}
|
|
|
|
_Myt& operator*=(const _Myt& _Right)
|
|
{ // multiply by other complex
|
|
_Mul(_Right);
|
|
return (*this);
|
|
}
|
|
|
|
_Myt& operator/=(const _Myt& _Right)
|
|
{ // divide by other complex
|
|
_Div(_Right);
|
|
return (*this);
|
|
}
|
|
|
|
template<class _Other> inline
|
|
_Myt& operator+=(const complex<_Other>& _Right)
|
|
{ // add other complex
|
|
_Add(_Right);
|
|
return (*this);
|
|
}
|
|
|
|
template<class _Other> inline
|
|
_Myt& operator-=(const complex<_Other>& _Right)
|
|
{ // subtract other complex
|
|
_Sub(_Right);
|
|
return (*this);
|
|
}
|
|
|
|
template<class _Other> inline
|
|
_Myt& operator*=(const complex<_Other>& _Right)
|
|
{ // multiply by other complex
|
|
_Mul(_Right);
|
|
return (*this);
|
|
}
|
|
|
|
template<class _Other> inline
|
|
_Myt& operator/=(const complex<_Other>& _Right)
|
|
{ // divide by other complex
|
|
_Div(_Right);
|
|
return (*this);
|
|
}
|
|
};
|
|
|
|
// CLASS complex<long double>
|
|
template<> class _CRTIMP2 complex<long double>
|
|
: public _Complex_base<long double>
|
|
{ // complex with long double components
|
|
public:
|
|
typedef long double _Ty;
|
|
typedef complex<_Ty> _Myt;
|
|
|
|
complex(const complex<float>&); // defined below
|
|
|
|
complex(const complex<double>&); // defined below
|
|
|
|
complex(const _Ty& _Realval = 0, const _Ty& _Imagval = 0)
|
|
: _Complex_base<_Ty>(_Realval, _Imagval)
|
|
{ // construct from long double components
|
|
}
|
|
|
|
complex<_Ty>& operator=(const _Ty& _Right)
|
|
{ // assign real
|
|
_Real = _Right;
|
|
_Imag = 0;
|
|
return (*this);
|
|
}
|
|
|
|
_Myt& operator+=(const _Ty& _Right)
|
|
{ // add real
|
|
_Real = _Real + _Right;
|
|
return (*this);
|
|
}
|
|
|
|
_Myt& operator-=(const _Ty& _Right)
|
|
{ // subtract real
|
|
_Real = _Real - _Right;
|
|
return (*this);
|
|
}
|
|
|
|
_Myt& operator*=(const _Ty& _Right)
|
|
{ // multiply by real
|
|
_Real = _Real * _Right;
|
|
_Imag = _Imag * _Right;
|
|
return (*this);
|
|
}
|
|
|
|
_Myt& operator/=(const _Ty& _Right)
|
|
{ // divide by real
|
|
_Real = _Real / _Right;
|
|
_Imag = _Imag / _Right;
|
|
return (*this);
|
|
}
|
|
|
|
_Myt& operator+=(const _Myt& _Right)
|
|
{ // add other complex
|
|
_Add(_Right);
|
|
return (*this);
|
|
}
|
|
|
|
_Myt& operator-=(const _Myt& _Right)
|
|
{ // subtract other complex
|
|
_Sub(_Right);
|
|
return (*this);
|
|
}
|
|
|
|
_Myt& operator*=(const _Myt& _Right)
|
|
{ // multiply by other complex
|
|
_Mul(_Right);
|
|
return (*this);
|
|
}
|
|
|
|
_Myt& operator/=(const _Myt& _Right)
|
|
{ // divide by other complex
|
|
_Div(_Right);
|
|
return (*this);
|
|
}
|
|
|
|
template<class _Other> inline
|
|
_Myt& operator+=(const complex<_Other>& _Right)
|
|
{ // add other complex
|
|
_Add(_Right);
|
|
return (*this);
|
|
}
|
|
|
|
template<class _Other> inline
|
|
_Myt& operator-=(const complex<_Other>& _Right)
|
|
{ // subtract other complex
|
|
_Sub(_Right);
|
|
return (*this);
|
|
}
|
|
|
|
template<class _Other> inline
|
|
_Myt& operator*=(const complex<_Other>& _Right)
|
|
{ // multiply by other complex
|
|
_Mul(_Right);
|
|
return (*this);
|
|
}
|
|
|
|
template<class _Other> inline
|
|
_Myt& operator/=(const complex<_Other>& _Right)
|
|
{ // divide by other complex
|
|
_Div(_Right);
|
|
return (*this);
|
|
}
|
|
};
|
|
|
|
// CONSTRUCTORS FOR complex SPECIALIZATIONS
|
|
_TEMPLATE_STAT inline
|
|
complex<float>::complex(const complex<double>& _Right)
|
|
: _Complex_base<float>((_Ty)_Right.real(), (_Ty)_Right.imag())
|
|
{ // construct complex<float> from complex<double>
|
|
}
|
|
|
|
_TEMPLATE_STAT inline
|
|
complex<float>::complex(const complex<long double>& _Right)
|
|
: _Complex_base<float>((_Ty)_Right.real(), (_Ty)_Right.imag())
|
|
{ // construct complex<float> from complex<long double>
|
|
}
|
|
|
|
_TEMPLATE_STAT inline
|
|
complex<double>::complex(const complex<float>& _Right)
|
|
: _Complex_base<double>((_Ty)_Right.real(), (_Ty)_Right.imag())
|
|
{ // construct complex<double> from complex<float>
|
|
}
|
|
|
|
_TEMPLATE_STAT inline
|
|
complex<double>::complex(const complex<long double>& _Right)
|
|
: _Complex_base<double>((_Ty)_Right.real(), (_Ty)_Right.imag())
|
|
{ // construct complex<double> from complex<long double>
|
|
}
|
|
|
|
_TEMPLATE_STAT inline
|
|
complex<long double>::complex(const complex<float>& _Right)
|
|
: _Complex_base<long double>((_Ty)_Right.real(), (_Ty)_Right.imag())
|
|
{ // construct complex<long double> from complex<float>
|
|
}
|
|
|
|
_TEMPLATE_STAT inline
|
|
complex<long double>::complex(const complex<double>& _Right)
|
|
: _Complex_base<long double>((_Ty)_Right.real(), (_Ty)_Right.imag())
|
|
{ // construct complex<long double> from complex<double>
|
|
}
|
|
|
|
// TEMPLATE CLASS complex
|
|
template<class _Ty>
|
|
class complex
|
|
: public _Complex_base<_Ty>
|
|
{ // complex with _Ty components
|
|
public:
|
|
typedef complex<_Ty> _Myt;
|
|
typedef _Complex_base<_Ty> _Mybase;
|
|
|
|
complex(const _Ty& _Realval = 0, const _Ty& _Imagval = 0)
|
|
: _Mybase(_Realval, _Imagval)
|
|
{ // construct from components of same type
|
|
}
|
|
|
|
_Myt& operator=(const _Ty& _Right)
|
|
{ // assign real
|
|
this->_Real = _Right;
|
|
this->_Imag = 0;
|
|
return (*this);
|
|
}
|
|
|
|
template<class _Other>
|
|
complex(const complex<_Other>& _Right)
|
|
: _Mybase((_Ty)_Right.real(), (_Ty)_Right.imag())
|
|
{ // construct from other complex type
|
|
}
|
|
|
|
template<class _Other>
|
|
_Myt& operator=(const complex<_Other>& _Right)
|
|
{ // assign other complex type
|
|
this->_Real = (_Ty)_Right.real();
|
|
this->_Imag = (_Ty)_Right.imag();
|
|
return (*this);
|
|
}
|
|
|
|
_Myt& operator+=(const _Ty& _Right)
|
|
{ // add real
|
|
this->_Real = this->_Real + _Right;
|
|
return (*this);
|
|
}
|
|
|
|
_Myt& operator-=(const _Ty& _Right)
|
|
{ // subtract real
|
|
this->_Real = this->_Real - _Right;
|
|
return (*this);
|
|
}
|
|
|
|
_Myt& operator*=(const _Ty& _Right)
|
|
{ // multiply by real
|
|
this->_Real = this->_Real * _Right;
|
|
this->_Imag = this->_Imag * _Right;
|
|
return (*this);
|
|
}
|
|
|
|
_Myt& operator/=(const _Ty& _Right)
|
|
{ // divide by real
|
|
this->_Real = this->_Real / _Right;
|
|
this->_Imag = this->_Imag / _Right;
|
|
return (*this);
|
|
}
|
|
|
|
_Myt& operator+=(const _Myt& _Right)
|
|
{ // add other complex
|
|
_Add(_Right);
|
|
return (*this);
|
|
}
|
|
|
|
_Myt& operator-=(const _Myt& _Right)
|
|
{ // subtract other complex
|
|
_Sub(_Right);
|
|
return (*this);
|
|
}
|
|
|
|
_Myt& operator*=(const _Myt& _Right)
|
|
{ // multiply by other complex
|
|
_Mul(_Right);
|
|
return (*this);
|
|
}
|
|
|
|
_Myt& operator/=(const _Myt& _Right)
|
|
{ // divide by other complex
|
|
_Div(_Right);
|
|
return (*this);
|
|
}
|
|
|
|
template<class _Other> inline
|
|
_Myt& operator+=(const complex<_Other>& _Right)
|
|
{ // add other complex
|
|
this->_Add(_Right);
|
|
return (*this);
|
|
}
|
|
|
|
template<class _Other> inline
|
|
_Myt& operator-=(const complex<_Other>& _Right)
|
|
{ // subtract other complex
|
|
this->_Sub(_Right);
|
|
return (*this);
|
|
}
|
|
|
|
template<class _Other> inline
|
|
_Myt& operator*=(const complex<_Other>& _Right)
|
|
{ // multiply by other complex
|
|
this->_Mul(_Right);
|
|
return (*this);
|
|
}
|
|
|
|
template<class _Other> inline
|
|
_Myt& operator/=(const complex<_Other>& _Right)
|
|
{ // divide by other complex
|
|
this->_Div(_Right);
|
|
return (*this);
|
|
}
|
|
};
|
|
|
|
#define _CMPLX(T) complex<T >
|
|
#define _CTR(T) _Ctraits<T >
|
|
#define _TMPLT(T) template<class T >
|
|
#include <xcomplex> /* define all complex template functions */
|
|
|
|
|
|
// TEMPLATE FUNCTION operator>>
|
|
template<class _Ty,
|
|
class _Elem,
|
|
class _Tr> inline
|
|
basic_istream<_Elem, _Tr>& __cdecl operator>>(
|
|
basic_istream<_Elem, _Tr>& _Istr, complex<_Ty>& _Right)
|
|
{ // extract a complex<_Ty>
|
|
typedef complex<_Ty> _Myt;
|
|
_Elem _Ch;
|
|
long double _Real, _Imag = 0;
|
|
|
|
if (_Istr >> _Ch && _Ch != '(')
|
|
{ // no leading '(', treat as real only
|
|
_Istr.putback(_Ch);
|
|
_Istr >> _Real;
|
|
_Imag = 0;
|
|
}
|
|
else if (_Istr >> _Real >> _Ch && _Ch != ',')
|
|
if (_Ch == ')')
|
|
_Imag = 0; // (real)
|
|
else
|
|
{ // no trailing ')' after real, treat as bad field
|
|
_Istr.putback(_Ch);
|
|
_Istr.setstate(ios_base::failbit);
|
|
}
|
|
else if (_Istr >> _Imag >> _Ch && _Ch != ')')
|
|
{ // no imag or trailing ')', treat as bad field
|
|
_Istr.putback(_Ch);
|
|
_Istr.setstate(ios_base::failbit);
|
|
}
|
|
|
|
if (!_Istr.fail())
|
|
{ // store valid result
|
|
_Ty _Tyreal((_Ty)_Real), _Tyimag((_Ty)_Imag);
|
|
_Right = _Myt(_Tyreal, _Tyimag);
|
|
}
|
|
return (_Istr);
|
|
}
|
|
|
|
// TEMPLATE FUNCTION operator<<
|
|
template<class _Ty,
|
|
class _Elem,
|
|
class _Tr> inline
|
|
basic_ostream<_Elem, _Tr>& __cdecl operator<<(
|
|
basic_ostream<_Elem, _Tr>& _Ostr, const complex<_Ty>& _Right)
|
|
{ // insert a complex<_Ty>
|
|
basic_ostringstream<_Elem, _Tr, allocator<_Elem> > _Sstr;
|
|
|
|
_Sstr.flags(_Ostr.flags());
|
|
_Sstr.imbue(_Ostr.getloc());
|
|
_Sstr.precision(_Ostr.precision());
|
|
_Sstr << '(' << real(_Right) << ',' << imag(_Right) << ')';
|
|
|
|
basic_string<_Elem, _Tr, allocator<_Elem> > _Str = _Sstr.str();
|
|
return (_Ostr << _Str.c_str());
|
|
}
|
|
|
|
#ifdef _DLL_CPPLIB
|
|
#ifndef CRTDLL2
|
|
template _CRTIMP2 basic_istream<char, char_traits<char> >&
|
|
__cdecl operator>>(basic_istream<char, char_traits<char> >&,
|
|
complex<float>&);
|
|
template _CRTIMP2 basic_ostream<char, char_traits<char> >&
|
|
__cdecl operator<<(basic_ostream<char, char_traits<char> >&,
|
|
const complex<float>&);
|
|
template _CRTIMP2 basic_istream<wchar_t, char_traits<wchar_t> >&
|
|
__cdecl operator>>(basic_istream<wchar_t, char_traits<wchar_t> >&,
|
|
complex<float>&);
|
|
template _CRTIMP2 basic_ostream<wchar_t, char_traits<wchar_t> >&
|
|
__cdecl operator<<(basic_ostream<wchar_t, char_traits<wchar_t> >&,
|
|
const complex<float>&);
|
|
#ifdef _CRTBLD_NATIVE_WCHAR_T
|
|
template _CRTIMP2 basic_istream<unsigned short, char_traits<unsigned short> >&
|
|
__cdecl operator>>(basic_istream<unsigned short, char_traits<unsigned short> >&,
|
|
complex<float>&);
|
|
template _CRTIMP2 basic_ostream<unsigned short, char_traits<unsigned short> >&
|
|
__cdecl operator<<(basic_ostream<unsigned short, char_traits<unsigned short> >&,
|
|
const complex<float>&);
|
|
#endif
|
|
|
|
template _CRTIMP2 basic_istream<char, char_traits<char> >&
|
|
__cdecl operator>>(basic_istream<char, char_traits<char> >&,
|
|
complex<double>&);
|
|
template _CRTIMP2 basic_ostream<char, char_traits<char> >&
|
|
__cdecl operator<<(basic_ostream<char, char_traits<char> >&,
|
|
const complex<double>&);
|
|
template _CRTIMP2 basic_istream<wchar_t, char_traits<wchar_t> >&
|
|
__cdecl operator>>(basic_istream<wchar_t, char_traits<wchar_t> >&,
|
|
complex<double>&);
|
|
template _CRTIMP2 basic_ostream<wchar_t, char_traits<wchar_t> >&
|
|
__cdecl operator<<(basic_ostream<wchar_t, char_traits<wchar_t> >&,
|
|
const complex<double>&);
|
|
#ifdef _CRTBLD_NATIVE_WCHAR_T
|
|
template _CRTIMP2 basic_istream<unsigned short, char_traits<unsigned short> >&
|
|
__cdecl operator>>(basic_istream<unsigned short, char_traits<unsigned short> >&,
|
|
complex<double>&);
|
|
template _CRTIMP2 basic_ostream<unsigned short, char_traits<unsigned short> >&
|
|
__cdecl operator<<(basic_ostream<unsigned short, char_traits<unsigned short> >&,
|
|
const complex<double>&);
|
|
#endif
|
|
|
|
template _CRTIMP2 basic_istream<char, char_traits<char> >&
|
|
__cdecl operator>>(basic_istream<char, char_traits<char> >&,
|
|
complex<long double>&);
|
|
template _CRTIMP2 basic_ostream<char, char_traits<char> >&
|
|
__cdecl operator<<(basic_ostream<char, char_traits<char> >&,
|
|
const complex<long double>&);
|
|
template _CRTIMP2 basic_istream<wchar_t, char_traits<wchar_t> >&
|
|
__cdecl operator>>(basic_istream<wchar_t, char_traits<wchar_t> >&,
|
|
complex<long double>&);
|
|
template _CRTIMP2 basic_ostream<wchar_t, char_traits<wchar_t> >&
|
|
__cdecl operator<<(basic_ostream<wchar_t, char_traits<wchar_t> >&,
|
|
const complex<long double>&);
|
|
#ifdef _CRTBLD_NATIVE_WCHAR_T
|
|
template _CRTIMP2 basic_istream<unsigned short, char_traits<unsigned short> >&
|
|
__cdecl operator>>(basic_istream<unsigned short, char_traits<unsigned short> >&,
|
|
complex<long double>&);
|
|
template _CRTIMP2 basic_ostream<unsigned short, char_traits<unsigned short> >&
|
|
__cdecl operator<<(basic_ostream<unsigned short, char_traits<unsigned short> >&,
|
|
const complex<long double>&);
|
|
#endif
|
|
#endif // CRTDLL2
|
|
#endif // _DLL_CPPLIB
|
|
_STD_END
|
|
#pragma warning(default: 4244)
|
|
#pragma warning(pop)
|
|
#pragma pack(pop)
|
|
|
|
#endif /* _COMPLEX_ */
|
|
|
|
/*
|
|
* Copyright (c) 1992-2001 by P.J. Plauger. ALL RIGHTS RESERVED.
|
|
* Consult your license regarding permissions and restrictions.
|
|
V3.10:0009 */
|