1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/genericopenlibs/cppstdlib/stl/src/complex_trig.cpp Fri Jun 15 03:10:57 2012 +0200
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 + static const long double 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 + static const long double ldouble_limit = M_LN2l * LDBL_MAX_EXP;
1.61 +# else
1.62 + static const long double 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