1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/build/stlport/src/complex_trig.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,192 @@ 1.4 +/* 1.5 + * Copyright (c) 1999 1.6 + * Silicon Graphics Computer Systems, Inc. 1.7 + * 1.8 + * Copyright (c) 1999 1.9 + * Boris Fomitchev 1.10 + * 1.11 + * This material is provided "as is", with absolutely no warranty expressed 1.12 + * or implied. Any use is at your own risk. 1.13 + * 1.14 + * Permission to use or copy this software for any purpose is hereby granted 1.15 + * without fee, provided the above notices are retained on all copies. 1.16 + * Permission to modify the code and to distribute modified code is granted, 1.17 + * provided the above notices are retained, and a notice that the code was 1.18 + * modified is included with the above copyright notice. 1.19 + * 1.20 + */ 1.21 +#include "stlport_prefix.h" 1.22 + 1.23 + 1.24 +// Trigonometric and hyperbolic functions for complex<float>, 1.25 +// complex<double>, and complex<long double> 1.26 +#include <complex> 1.27 +#include <cfloat> 1.28 +#include <cmath> 1.29 + 1.30 +_STLP_BEGIN_NAMESPACE 1.31 + 1.32 + 1.33 +//---------------------------------------------------------------------- 1.34 +// helpers 1.35 +#if defined (__sgi) 1.36 + static const union { unsigned int i; float f; } float_ulimit = { 0x42b2d4fc }; 1.37 + static const float float_limit = float_ulimit.f; 1.38 + static union { 1.39 + struct { unsigned int h; unsigned int l; } w; 1.40 + double d; 1.41 + } double_ulimit = { 0x408633ce, 0x8fb9f87d }; 1.42 + static const double double_limit = double_ulimit.d; 1.43 + static union { 1.44 + struct { unsigned int h[2]; unsigned int l[2]; } w; 1.45 + long double ld; 1.46 + } ldouble_ulimit = {0x408633ce, 0x8fb9f87e, 0xbd23b659, 0x4e9bd8b1}; 1.47 +# if !defined (_STLP_NO_LONG_DOUBLE) 1.48 +# define ldouble_limit ldouble_ulimit.ld 1.49 +# endif 1.50 +#else 1.51 +# if defined (M_LN2) && defined (FLT_MAX_EXP) 1.52 + static const float float_limit = float(M_LN2 * FLT_MAX_EXP); 1.53 + static const double double_limit = M_LN2 * DBL_MAX_EXP; 1.54 +# else 1.55 + static const float float_limit = ::log(FLT_MAX); 1.56 + static const double double_limit = ::log(DBL_MAX); 1.57 +# endif 1.58 +# if !defined (_STLP_NO_LONG_DOUBLE) 1.59 +# if defined (M_LN2l) 1.60 +# define ldouble_limit (M_LN2l * LDBL_MAX_EXP) 1.61 +# else 1.62 +# define ldouble_limit ::log(LDBL_MAX) 1.63 +# endif 1.64 +# endif 1.65 +#endif 1.66 + 1.67 + 1.68 +//---------------------------------------------------------------------- 1.69 +// sin 1.70 +template <class _Tp> 1.71 +static complex<_Tp> sinT(const complex<_Tp>& z) { 1.72 + return complex<_Tp>(::sin(z._M_re) * ::cosh(z._M_im), 1.73 + ::cos(z._M_re) * ::sinh(z._M_im)); 1.74 +} 1.75 + 1.76 +_STLP_DECLSPEC complex<float> _STLP_CALL sin(const complex<float>& z) 1.77 +{ return sinT(z); } 1.78 + 1.79 +_STLP_DECLSPEC complex<double> _STLP_CALL sin(const complex<double>& z) 1.80 +{ return sinT(z); } 1.81 + 1.82 +#if !defined (_STLP_NO_LONG_DOUBLE) 1.83 +_STLP_DECLSPEC complex<long double> _STLP_CALL sin(const complex<long double>& z) 1.84 +{ return sinT(z); } 1.85 +#endif 1.86 + 1.87 +//---------------------------------------------------------------------- 1.88 +// cos 1.89 +template <class _Tp> 1.90 +static complex<_Tp> cosT(const complex<_Tp>& z) { 1.91 + return complex<_Tp>(::cos(z._M_re) * ::cosh(z._M_im), 1.92 + -::sin(z._M_re) * ::sinh(z._M_im)); 1.93 +} 1.94 + 1.95 +_STLP_DECLSPEC complex<float> _STLP_CALL cos(const complex<float>& z) 1.96 +{ return cosT(z); } 1.97 + 1.98 +_STLP_DECLSPEC complex<double> _STLP_CALL cos(const complex<double>& z) 1.99 +{ return cosT(z); } 1.100 + 1.101 +#if !defined (_STLP_NO_LONG_DOUBLE) 1.102 +_STLP_DECLSPEC complex<long double> _STLP_CALL cos(const complex<long double>& z) 1.103 +{ return cosT(z); } 1.104 +#endif 1.105 + 1.106 +//---------------------------------------------------------------------- 1.107 +// tan 1.108 +template <class _Tp> 1.109 +static complex<_Tp> tanT(const complex<_Tp>& z, const _Tp& Tp_limit) { 1.110 + _Tp re2 = 2.f * z._M_re; 1.111 + _Tp im2 = 2.f * z._M_im; 1.112 + 1.113 + if (::abs(im2) > Tp_limit) 1.114 + return complex<_Tp>(0.f, (im2 > 0 ? 1.f : -1.f)); 1.115 + else { 1.116 + _Tp den = ::cos(re2) + ::cosh(im2); 1.117 + return complex<_Tp>(::sin(re2) / den, ::sinh(im2) / den); 1.118 + } 1.119 +} 1.120 + 1.121 +_STLP_DECLSPEC complex<float> _STLP_CALL tan(const complex<float>& z) 1.122 +{ return tanT(z, float_limit); } 1.123 + 1.124 +_STLP_DECLSPEC complex<double> _STLP_CALL tan(const complex<double>& z) 1.125 +{ return tanT(z, double_limit); } 1.126 + 1.127 +#if !defined (_STLP_NO_LONG_DOUBLE) 1.128 +_STLP_DECLSPEC complex<long double> _STLP_CALL tan(const complex<long double>& z) 1.129 +{ return tanT(z, ldouble_limit); } 1.130 +#endif 1.131 + 1.132 +//---------------------------------------------------------------------- 1.133 +// sinh 1.134 +template <class _Tp> 1.135 +static complex<_Tp> sinhT(const complex<_Tp>& z) { 1.136 + return complex<_Tp>(::sinh(z._M_re) * ::cos(z._M_im), 1.137 + ::cosh(z._M_re) * ::sin(z._M_im)); 1.138 +} 1.139 + 1.140 +_STLP_DECLSPEC complex<float> _STLP_CALL sinh(const complex<float>& z) 1.141 +{ return sinhT(z); } 1.142 + 1.143 +_STLP_DECLSPEC complex<double> _STLP_CALL sinh(const complex<double>& z) 1.144 +{ return sinhT(z); } 1.145 + 1.146 +#if !defined (_STLP_NO_LONG_DOUBLE) 1.147 +_STLP_DECLSPEC complex<long double> _STLP_CALL sinh(const complex<long double>& z) 1.148 +{ return sinhT(z); } 1.149 +#endif 1.150 + 1.151 +//---------------------------------------------------------------------- 1.152 +// cosh 1.153 +template <class _Tp> 1.154 +static complex<_Tp> coshT(const complex<_Tp>& z) { 1.155 + return complex<_Tp>(::cosh(z._M_re) * ::cos(z._M_im), 1.156 + ::sinh(z._M_re) * ::sin(z._M_im)); 1.157 +} 1.158 + 1.159 +_STLP_DECLSPEC complex<float> _STLP_CALL cosh(const complex<float>& z) 1.160 +{ return coshT(z); } 1.161 + 1.162 +_STLP_DECLSPEC complex<double> _STLP_CALL cosh(const complex<double>& z) 1.163 +{ return coshT(z); } 1.164 + 1.165 +#if !defined (_STLP_NO_LONG_DOUBLE) 1.166 +_STLP_DECLSPEC complex<long double> _STLP_CALL cosh(const complex<long double>& z) 1.167 +{ return coshT(z); } 1.168 +#endif 1.169 + 1.170 +//---------------------------------------------------------------------- 1.171 +// tanh 1.172 +template <class _Tp> 1.173 +static complex<_Tp> tanhT(const complex<_Tp>& z, const _Tp& Tp_limit) { 1.174 + _Tp re2 = 2.f * z._M_re; 1.175 + _Tp im2 = 2.f * z._M_im; 1.176 + if (::abs(re2) > Tp_limit) 1.177 + return complex<_Tp>((re2 > 0 ? 1.f : -1.f), 0.f); 1.178 + else { 1.179 + _Tp den = ::cosh(re2) + ::cos(im2); 1.180 + return complex<_Tp>(::sinh(re2) / den, ::sin(im2) / den); 1.181 + } 1.182 +} 1.183 + 1.184 +_STLP_DECLSPEC complex<float> _STLP_CALL tanh(const complex<float>& z) 1.185 +{ return tanhT(z, float_limit); } 1.186 + 1.187 +_STLP_DECLSPEC complex<double> _STLP_CALL tanh(const complex<double>& z) 1.188 +{ return tanhT(z, double_limit); } 1.189 + 1.190 +#if !defined (_STLP_NO_LONG_DOUBLE) 1.191 +_STLP_DECLSPEC complex<long double> _STLP_CALL tanh(const complex<long double>& z) 1.192 +{ return tanhT(z, ldouble_limit); } 1.193 +#endif 1.194 + 1.195 +_STLP_END_NAMESPACE