简介:
复数运算在数学领域非常重要,而且C++标准库也完备的实现了关于复数的几乎所有运算。要使用compelx类需要包含文件
实现:
complex类被定义和实现在
文件首先定义了三种数据结构: _C_double_complex(_Dcomplex_value)、_C_float_complex(_Fcomplex_value)、_C_ldouble_complex(_Lcomplex_value)。这些数据结构的意义在于定义了不同类型的complex的内存存储结构。如下:
typedef struct _C_double_complex
{ /* double complex */
double _Val[2];
} _C_double_complex;
typedef struct _C_float_complex
{ /* float complex */
float _Val[2];
} _C_float_complex;
typedef struct _C_ldouble_complex
{ /* long double complex */
long double _Val[2];
} _C_ldouble_complex;
typedef _CSTD _C_double_complex _Dcomplex_value;
typedef _CSTD _C_float_complex _Fcomplex_value;
typedef _CSTD _C_ldouble_complex _Lcomplex_value;
可以看到它的内部使用空间为2的数组来实现。然后文件前置声明了complex类的原型和三种特化版本:complex<float>、complex<double>、complex<long double>。
template<class _Ty> class complex;
template<> class complex<float>;
template<> class complex<double>;
template<> class complex<long double>;
所以我们在使用complex类的时候就可以定义成:
complex<float> fcomplex;
complex<double> dcomplex;
complex<long double> lcomplex;
接下来定义了一个_Ctraits类,该类的作用是定义了一些基本数据类型(如double、float、long double等)拥有的特性(如_Isinf(是否为无穷小)、_Isnan(是否为无穷大)等)以及可实现的函数运算集合(如cos(余弦函数)、tan(正切函数)等):
// TEMPLATE CLASS _Ctraits
template<class _Ty> class _Ctraits
{ // complex traits for _Ty
public:
static _Ty _Cosh(_Ty _Left, _Ty _Right);
static short _Exp(_Ty *_Pleft, _Ty _Right, short _Exponent);
static _Ty _Infv(_Ty);
static bool _Isinf(_Ty _Left);
static bool _Isnan(_Ty _Left);
static _Ty _Nanv(_Ty);
static _Ty _Sinh(_Ty _Left, _Ty _Right);
static _Ty atan2(_Ty _Yval, _Ty _Xval);
static _Ty cos(_Ty _Left);
static _Ty exp(_Ty _Left);
static _Ty ldexp(_Ty _Left, int _Exponent);
static _Ty log(_Ty _Left);
static _Ty pow(_Ty _Left, _Ty _Right);
static _Ty sin(_Ty _Left);
static _Ty sqrt(_Ty _Left);
static _Ty tan(_Ty _Left);
};
针对_Ctraits类的特化版本有三个:
// CLASS _Ctraits
template<> class _Ctraits<long double>;
// CLASS _Ctraits
template<> class _Ctraits<double>;
// CLASS _Ctraits
template<> class _Ctraits<float>;
然后定义了一个存储模板_Complex_value,用来为complex类提供存储结构:
// TEMPLATE CLASS _Complex_value
template<class _Ty> struct _Complex_value
{ /* templatized complex value */
enum {_Re = 0, _Im = 1};
_Ty _Val[2];
};
实际上文件已开始提到的那三个结构体(_Dcomplex_value、_Fcomplex_value、_Lcomplex_value)可以看做是_Complex_value的三个特化版本。
再接下来是从_Complex_value结构派生出_Complex_base类,主要提供取实部和虚部以及加减乘除的基本运算的函数。_Complex_base有两个模板参数,其中_Ty是基本数据类型,如double、float,_Valbase是存储结构,如_Dcomplex_value、_Fcomplex_value。而且请注意这里有很重要的一点:_Complex_base继承自模板参数_Valbase。
// TEMPLATE CLASS _Complex_base
template<class _Ty, class _Valbase> class _Complex_base : public _Valbase
{ // base for all complex types
public:
typedef _Ctraits<_Ty> _Myctraits;
typedef _Complex_base<_Ty, _Valbase> _Myt;
typedef _Ty value_type;
_Complex_base(const _Ty& _Realval, const _Ty& _Imagval);
_Ty real(const _Ty& _Right);
_Ty imag(const _Ty& _Right);
_Ty real() ;
_Ty imag() const;
protected:
template<class _Other> inline void _Add(const complex<_Other>& _Right);
template<class _Other> inline void _Sub(const complex<_Other>& _Right);
template<class _Other> inline void _Mul(const complex<_Other>& _Right);
template<class _Other> inline void _Div(const complex<_Other>& _Right);
};
接下来有点怪异,因为complex的定义被放在了complex的特化版本之后。这里就先讲complex模板的实现。complex类继承自_Complex_base类,并且已经实现成了只有一个模板参数_Ty,但是我们知道_Complex_base类有两个模板参数,此时先前定义的那个_Complex_value模板就有作用了。然后结合后面的complex特化版本定义,就验证了我之前说过的“文件已开始提到的那三个结构体(_Dcomplex_value、_Fcomplex_value、_Lcomplex_value)可以看做是_Complex_value的三个特化版本”是正确的,知识没有采用明显的模板定义。至于为什么,我还没有想明白。如果读者知道为什么请告诉我一声。
// TEMPLATE CLASS complex
template<class _Ty> class complex : public _Complex_base<_Ty, _Complex_value<_Ty> >
{ // complex with _Ty components
public:
typedef complex<_Ty> _Myt;
typedef _Complex_base<_Ty, _Complex_value<_Ty> > _Mybase;
complex(const _Ty& _Realval = _Ty(), const _Ty& _Imagval = _Ty());
_Myt& operator=(const _Ty& _Right);
template<class _Other> complex(const complex<_Other>& _Right);
template<class _Other> _Myt& operator=(const complex<_Other>& _Right);
_Myt& operator+=(const _Ty& _Right);
_Myt& operator-=(const _Ty& _Right);
_Myt& operator*=(const _Ty& _Right);
_Myt& operator/=(const _Ty& _Right);
_Myt& operator+=(const _Myt& _Right);
_Myt& operator-=(const _Myt& _Right);
_Myt& operator*=(const _Myt& _Right);
_Myt& operator/=(const _Myt& _Right);
template<class _Other> inline _Myt& operator+=(const complex<_Other>& _Right);
template<class _Other> inline _Myt& operator-=(const complex<_Other>& _Right);
template<class _Other> inline _Myt& operator*=(const complex<_Other>& _Right);
template<class _Other> inline _Myt& operator/=(const complex<_Other>& _Right);
};
接下来是complex类的三个特化版本:
complex<float>、complex<double>、complex<long double>。
// CLASS complex
template<> class complex<float> : public _Complex_base<float, _Fcomplex_value>
{ // 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(const _Fcomplex_value& _Right);
complex(const _Dcomplex_value& _Right);
complex(const _Lcomplex_value& _Right);
complex<_Ty>& operator=(const _Ty& _Right);
_Myt& operator+=(const _Ty& _Right);
_Myt& operator-=(const _Ty& _Right);
_Myt& operator*=(const _Ty& _Right);
_Myt& operator/=(const _Ty& _Right);
_Myt& operator+=(const _Myt& _Right);
_Myt& operator-=(const _Myt& _Right);
_Myt& operator*=(const _Myt& _Right);
_Myt& operator/=(const _Myt& _Right);
template<class _Other> inline _Myt& operator=(const complex<_Other>& _Right);
template<class _Other> inline _Myt& operator+=(const complex<_Other>& _Right);
template<class _Other> inline _Myt& operator-=(const complex<_Other>& _Right);
template<class _Other> inline _Myt& operator*=(const complex<_Other>& _Right);
template<class _Other> inline _Myt& operator/=(const complex<_Other>& _Right);
};
// CLASS complex
template<> class complex<double> : public _Complex_base<double, _Dcomplex_value>
{ // 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(const _Dcomplex_value& _Right);
complex(const _Lcomplex_value& _Right);
complex<_Ty>& operator=(const _Ty& _Right);
_Myt& operator+=(const _Ty& _Right);
_Myt& operator-=(const _Ty& _Right);
_Myt& operator*=(const _Ty& _Right);
_Myt& operator/=(const _Ty& _Right);
_Myt& operator+=(const _Myt& _Right);
_Myt& operator-=(const _Myt& _Right);
_Myt& operator*=(const _Myt& _Right);
_Myt& operator/=(const _Myt& _Right);
template<class _Other> inline _Myt& operator=(const complex<_Other>& _Right);
template<class _Other> inline _Myt& operator+=(const complex<_Other>& _Right);
template<class _Other> inline _Myt& operator-=(const complex<_Other>& _Right);
template<class _Other> inline _Myt& operator*=(const complex<_Other>& _Right);
template<class _Other> inline _Myt& operator/=(const complex<_Other>& _Right);
};
// CLASS complex
template<> class complex<long double> : public _Complex_base<long double, _Lcomplex_value>
{ // 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(const _Lcomplex_value& _Right);
complex<_Ty>& operator=(const _Ty& _Right);
_Myt& operator+=(const _Ty& _Right);
_Myt& operator-=(const _Ty& _Right);
_Myt& operator*=(const _Ty& _Right);
_Myt& operator/=(const _Ty& _Right);
_Myt& operator+=(const _Myt& _Right);
_Myt& operator-=(const _Myt& _Right);
_Myt& operator*=(const _Myt& _Right);
_Myt& operator/=(const _Myt& _Right);
template<class _Other> inline _Myt& operator=(const complex<_Other>& _Right);
template<class _Other> inline _Myt& operator+=(const complex<_Other>& _Right);
template<class _Other> inline _Myt& operator-=(const complex<_Other>& _Right);
template<class _Other> inline _Myt& operator*=(const complex<_Other>& _Right);
template<class _Other> inline _Myt& operator/=(const complex<_Other>& _Right);
};
在
// TEMPLATE FUNCTION operator>>
template<class _Ty, class _Elem, class _Tr>
inline basic_istream<_Elem, _Tr>& operator>>
(basic_istream<_Elem, _Tr>& _Istr, complex<_Ty>& _Right);
// TEMPLATE FUNCTION operator<<
template<class _Ty, class _Elem, class _Tr>
inline basic_ostream<_Elem, _Tr>& operator<<
(basic_ostream<_Elem, _Tr>& _Ostr, const complex<_Ty>& _Right);
有心的读者读到这里可能会发觉,我们找不到关于complex类的三角函数之类的运算。原来这些运算被定义在了
#define _CMPLX(T) complex
#define _CTR(T) _Ctraits
#define _TMPLT(T) template<class T >
// TEMPLATE FUNCTION operator+
_TMPLT(_Ty) inline
_CMPLX(_Ty) operator+(const _CMPLX(_Ty)& _Left, const _CMPLX(_Ty)& _Right);
_TMPLT(_Ty) inline
_CMPLX(_Ty) operator+(const _CMPLX(_Ty)& _Left, const _Ty& _Right);
_TMPLT(_Ty) inline
_CMPLX(_Ty) operator+(const _Ty& _Left, const _CMPLX(_Ty)& _Right);
// TEMPLATE FUNCTION operator-
_TMPLT(_Ty) inline
_CMPLX(_Ty) operator-(const _CMPLX(_Ty)& _Left, const _CMPLX(_Ty)& _Right);
_TMPLT(_Ty) inline
_CMPLX(_Ty) operator-(const _CMPLX(_Ty)& _Left, const _Ty& _Right);
_TMPLT(_Ty) inline
_CMPLX(_Ty) operator-(const _Ty& _Left, const _CMPLX(_Ty)& _Right);
// TEMPLATE FUNCTION operator*
_TMPLT(_Ty) inline
_CMPLX(_Ty) operator*(const _CMPLX(_Ty)& _Left, const _CMPLX(_Ty)& _Right);
_TMPLT(_Ty) inline
_CMPLX(_Ty) operator*(const _CMPLX(_Ty)& _Left, const _Ty& _Right);
_TMPLT(_Ty) inline
_CMPLX(_Ty) operator*(const _Ty& _Left, const _CMPLX(_Ty)& _Right);
// TEMPLATE FUNCTION operator/
_TMPLT(_Ty) inline
_CMPLX(_Ty) operator/(const _CMPLX(_Ty)& _Left, const _CMPLX(_Ty)& _Right);
_TMPLT(_Ty) inline
_CMPLX(_Ty) operator/(const _CMPLX(_Ty)& _Left, const _Ty& _Right);
_TMPLT(_Ty) inline
_CMPLX(_Ty) operator/(const _Ty& _Left, const _CMPLX(_Ty)& _Right);
// TEMPLATE FUNCTION UNARY operator+
_TMPLT(_Ty) inline
_CMPLX(_Ty) operator+(const _CMPLX(_Ty)& _Left);
// TEMPLATE FUNCTION UNARY operator-
_TMPLT(_Ty) inline
_CMPLX(_Ty) operator-(const _CMPLX(_Ty)& _Left);
// TEMPLATE FUNCTION operator==
_TMPLT(_Ty) inline
bool operator==(const _CMPLX(_Ty)& _Left, const _CMPLX(_Ty)& _Right);
_TMPLT(_Ty) inline
bool operator==(const _CMPLX(_Ty)& _Left, const _Ty& _Right);
_TMPLT(_Ty) inline
bool operator==(const _Ty& _Left, const _CMPLX(_Ty)& _Right);
// TEMPLATE FUNCTION operator!=
_TMPLT(_Ty) inline
bool operator!=(const _CMPLX(_Ty)& _Left, const _CMPLX(_Ty)& _Right);
_TMPLT(_Ty) inline
bool operator!=(const _CMPLX(_Ty)& _Left, const _Ty& _Right);
_TMPLT(_Ty) inline
bool operator!=(const _Ty& _Left, const _CMPLX(_Ty)& _Right);
// TEMPLATE FUNCTION imag
_TMPLT(_Ty) inline
_Ty imag(const _CMPLX(_Ty)& _Left);
// TEMPLATE FUNCTION real
_TMPLT(_Ty) inline
_Ty real(const _CMPLX(_Ty)& _Left);
// TEMPLATE FUNCTION _Fabs
_TMPLT(_Ty) inline
_Ty _Fabs(const _CMPLX(_Ty)& _Left, int *_Pexp);
// TEMPLATE FUNCTION abs
_TMPLT(_Ty) inline
_Ty abs(const _CMPLX(_Ty)& _Left);
// TEMPLATE FUNCTION cosh
_TMPLT(_Ty) inline
_CMPLX(_Ty) cosh(const _CMPLX(_Ty)& _Left);
// TEMPLATE FUNCTION exp
_TMPLT(_Ty) inline
_CMPLX(_Ty) exp(const _CMPLX(_Ty)& _Left);
// TEMPLATE FUNCTION log
_TMPLT(_Ty) inline
_CMPLX(_Ty) log(const _CMPLX(_Ty)& _Left);
// TEMPLATE FUNCTION pow
_TMPLT(_Ty) inline
_CMPLX(_Ty) pow(const _CMPLX(_Ty)& _Left, const _Ty& _Right);
_TMPLT(_Ty) inline
_CMPLX(_Ty) pow(const _CMPLX(_Ty)& _Left, int _Right);
_TMPLT(_Ty) inline
_CMPLX(_Ty) pow(const _Ty& _Left, const _CMPLX(_Ty)& _Right);
_TMPLT(_Ty) inline
_CMPLX(_Ty) pow(const _CMPLX(_Ty)& _Left, const _CMPLX(_Ty)& _Right);
// TEMPLATE FUNCTION sinh
_TMPLT(_Ty) inline
_CMPLX(_Ty) sinh(const _CMPLX(_Ty)& _Left);
// TEMPLATE FUNCTION sqrt
_TMPLT(_Ty) inline
_CMPLX(_Ty) sqrt(const _CMPLX(_Ty)& _Left);
// TEMPLATE FUNCTION tanh
_TMPLT(_Ty) inline
_CMPLX(_Ty) tanh(const _CMPLX(_Ty)& _Left);
// TEMPLATE FUNCTION arg
_TMPLT(_Ty) inline
_Ty arg(const _CMPLX(_Ty)& _Left);
// TEMPLATE FUNCTION conj
_TMPLT(_Ty) inline
_CMPLX(_Ty) conj(const _CMPLX(_Ty)& _Left);
// TEMPLATE FUNCTION cos
_TMPLT(_Ty) inline
_CMPLX(_Ty) cos(const _CMPLX(_Ty)& _Left);
// TEMPLATE FUNCTION log10
_TMPLT(_Ty) inline
_CMPLX(_Ty) log10(const _CMPLX(_Ty)& _Left);
// TEMPLATE FUNCTION norm
_TMPLT(_Ty) inline
_Ty norm(const _CMPLX(_Ty)& _Left);
// TEMPLATE FUNCTION polar
_TMPLT(_Ty) inline
_CMPLX(_Ty) polar(const _Ty& _Rho, const _Ty& _Theta);
_TMPLT(_Ty) inline
_CMPLX(_Ty) polar(const _Ty& _Rho);
// TEMPLATE FUNCTION sin
_TMPLT(_Ty) inline
_CMPLX(_Ty) sin(const _CMPLX(_Ty)& _Left);
// TEMPLATE FUNCTION tan
_TMPLT(_Ty) inline
_CMPLX(_Ty) tan(const _CMPLX(_Ty)& _Left);
转自网易博客 架构师之路 http://blog.163.com/lvan100@yeah/blog/static/68117214201251753754185/
http://blog.163.com/lvan100@yeah/blog/static/6811721420125175391253/