/home/ntakagi/work/STLport-5.1.5/src/complex_trig.cppGo to the documentation of this file.00001 /* 00002 * Copyright (c) 1999 00003 * Silicon Graphics Computer Systems, Inc. 00004 * 00005 * Copyright (c) 1999 00006 * Boris Fomitchev 00007 * 00008 * This material is provided "as is", with absolutely no warranty expressed 00009 * or implied. Any use is at your own risk. 00010 * 00011 * Permission to use or copy this software for any purpose is hereby granted 00012 * without fee, provided the above notices are retained on all copies. 00013 * Permission to modify the code and to distribute modified code is granted, 00014 * provided the above notices are retained, and a notice that the code was 00015 * modified is included with the above copyright notice. 00016 * 00017 */ 00018 #include "stlport_prefix.h" 00019 00020 00021 // Trigonometric and hyperbolic functions for complex<float>, 00022 // complex<double>, and complex<long double> 00023 #include <complex> 00024 #include <cfloat> 00025 #include <cmath> 00026 00027 _STLP_BEGIN_NAMESPACE 00028 00029 00030 //---------------------------------------------------------------------- 00031 // helpers 00032 #if defined (__sgi) 00033 static const union { unsigned int i; float f; } float_ulimit = { 0x42b2d4fc }; 00034 static const float float_limit = float_ulimit.f; 00035 static union { 00036 struct { unsigned int h; unsigned int l; } w; 00037 double d; 00038 } double_ulimit = { 0x408633ce, 0x8fb9f87d }; 00039 static const double double_limit = double_ulimit.d; 00040 static union { 00041 struct { unsigned int h[2]; unsigned int l[2]; } w; 00042 long double ld; 00043 } ldouble_ulimit = {0x408633ce, 0x8fb9f87e, 0xbd23b659, 0x4e9bd8b1}; 00044 # if !defined (_STLP_NO_LONG_DOUBLE) 00045 static const long double ldouble_limit = ldouble_ulimit.ld; 00046 # endif 00047 #else 00048 # if defined (M_LN2) && defined (FLT_MAX_EXP) 00049 static const float float_limit = float(M_LN2 * FLT_MAX_EXP); 00050 static const double double_limit = M_LN2 * DBL_MAX_EXP; 00051 # else 00052 static const float float_limit = ::log(FLT_MAX); 00053 static const double double_limit = ::log(DBL_MAX); 00054 # endif 00055 # if !defined (_STLP_NO_LONG_DOUBLE) 00056 # if defined (M_LN2l) 00057 static const long double ldouble_limit = M_LN2l * LDBL_MAX_EXP; 00058 # else 00059 static const long double ldouble_limit = ::log(LDBL_MAX); 00060 # endif 00061 # endif 00062 #endif 00063 00064 00065 //---------------------------------------------------------------------- 00066 // sin 00067 template <class _Tp> 00068 static complex<_Tp> sinT(const complex<_Tp>& z) { 00069 return complex<_Tp>(::sin(z._M_re) * ::cosh(z._M_im), 00070 ::cos(z._M_re) * ::sinh(z._M_im)); 00071 } 00072 00073 _STLP_DECLSPEC complex<float> _STLP_CALL sin(const complex<float>& z) 00074 { return sinT(z); } 00075 00076 _STLP_DECLSPEC complex<double> _STLP_CALL sin(const complex<double>& z) 00077 { return sinT(z); } 00078 00079 #if !defined (_STLP_NO_LONG_DOUBLE) 00080 _STLP_DECLSPEC complex<long double> _STLP_CALL sin(const complex<long double>& z) 00081 { return sinT(z); } 00082 #endif 00083 00084 //---------------------------------------------------------------------- 00085 // cos 00086 template <class _Tp> 00087 static complex<_Tp> cosT(const complex<_Tp>& z) { 00088 return complex<_Tp>(::cos(z._M_re) * ::cosh(z._M_im), 00089 -::sin(z._M_re) * ::sinh(z._M_im)); 00090 } 00091 00092 _STLP_DECLSPEC complex<float> _STLP_CALL cos(const complex<float>& z) 00093 { return cosT(z); } 00094 00095 _STLP_DECLSPEC complex<double> _STLP_CALL cos(const complex<double>& z) 00096 { return cosT(z); } 00097 00098 #if !defined (_STLP_NO_LONG_DOUBLE) 00099 _STLP_DECLSPEC complex<long double> _STLP_CALL cos(const complex<long double>& z) 00100 { return cosT(z); } 00101 #endif 00102 00103 //---------------------------------------------------------------------- 00104 // tan 00105 template <class _Tp> 00106 static complex<_Tp> tanT(const complex<_Tp>& z, const _Tp& Tp_limit) { 00107 _Tp re2 = 2.f * z._M_re; 00108 _Tp im2 = 2.f * z._M_im; 00109 00110 if (::abs(im2) > Tp_limit) 00111 return complex<_Tp>(0.f, (im2 > 0 ? 1.f : -1.f)); 00112 else { 00113 _Tp den = ::cos(re2) + ::cosh(im2); 00114 return complex<_Tp>(::sin(re2) / den, ::sinh(im2) / den); 00115 } 00116 } 00117 00118 _STLP_DECLSPEC complex<float> _STLP_CALL tan(const complex<float>& z) 00119 { return tanT(z, float_limit); } 00120 00121 _STLP_DECLSPEC complex<double> _STLP_CALL tan(const complex<double>& z) 00122 { return tanT(z, double_limit); } 00123 00124 #if !defined (_STLP_NO_LONG_DOUBLE) 00125 _STLP_DECLSPEC complex<long double> _STLP_CALL tan(const complex<long double>& z) 00126 { return tanT(z, ldouble_limit); } 00127 #endif 00128 00129 //---------------------------------------------------------------------- 00130 // sinh 00131 template <class _Tp> 00132 static complex<_Tp> sinhT(const complex<_Tp>& z) { 00133 return complex<_Tp>(::sinh(z._M_re) * ::cos(z._M_im), 00134 ::cosh(z._M_re) * ::sin(z._M_im)); 00135 } 00136 00137 _STLP_DECLSPEC complex<float> _STLP_CALL sinh(const complex<float>& z) 00138 { return sinhT(z); } 00139 00140 _STLP_DECLSPEC complex<double> _STLP_CALL sinh(const complex<double>& z) 00141 { return sinhT(z); } 00142 00143 #if !defined (_STLP_NO_LONG_DOUBLE) 00144 _STLP_DECLSPEC complex<long double> _STLP_CALL sinh(const complex<long double>& z) 00145 { return sinhT(z); } 00146 #endif 00147 00148 //---------------------------------------------------------------------- 00149 // cosh 00150 template <class _Tp> 00151 static complex<_Tp> coshT(const complex<_Tp>& z) { 00152 return complex<_Tp>(::cosh(z._M_re) * ::cos(z._M_im), 00153 ::sinh(z._M_re) * ::sin(z._M_im)); 00154 } 00155 00156 _STLP_DECLSPEC complex<float> _STLP_CALL cosh(const complex<float>& z) 00157 { return coshT(z); } 00158 00159 _STLP_DECLSPEC complex<double> _STLP_CALL cosh(const complex<double>& z) 00160 { return coshT(z); } 00161 00162 #if !defined (_STLP_NO_LONG_DOUBLE) 00163 _STLP_DECLSPEC complex<long double> _STLP_CALL cosh(const complex<long double>& z) 00164 { return coshT(z); } 00165 #endif 00166 00167 //---------------------------------------------------------------------- 00168 // tanh 00169 template <class _Tp> 00170 static complex<_Tp> tanhT(const complex<_Tp>& z, const _Tp& Tp_limit) { 00171 _Tp re2 = 2.f * z._M_re; 00172 _Tp im2 = 2.f * z._M_im; 00173 if (::abs(re2) > Tp_limit) 00174 return complex<_Tp>((re2 > 0 ? 1.f : -1.f), 0.f); 00175 else { 00176 _Tp den = ::cosh(re2) + ::cos(im2); 00177 return complex<_Tp>(::sinh(re2) / den, ::sin(im2) / den); 00178 } 00179 } 00180 00181 _STLP_DECLSPEC complex<float> _STLP_CALL tanh(const complex<float>& z) 00182 { return tanhT(z, float_limit); } 00183 00184 _STLP_DECLSPEC complex<double> _STLP_CALL tanh(const complex<double>& z) 00185 { return tanhT(z, double_limit); } 00186 00187 #if !defined (_STLP_NO_LONG_DOUBLE) 00188 _STLP_DECLSPEC complex<long double> _STLP_CALL tanh(const complex<long double>& z) 00189 { return tanhT(z, ldouble_limit); } 00190 #endif 00191 00192 _STLP_END_NAMESPACE
Generated on Mon Mar 10 15:32:16 2008 by ![]() |