diff -r e20de85af2ee -r ce057bb09d0b genericopenlibs/cppstdlib/stl/src/complex_trig.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/genericopenlibs/cppstdlib/stl/src/complex_trig.cpp Fri Jun 04 16:20:51 2010 +0100 @@ -0,0 +1,192 @@ +/* + * Copyright (c) 1999 + * Silicon Graphics Computer Systems, Inc. + * + * Copyright (c) 1999 + * Boris Fomitchev + * + * This material is provided "as is", with absolutely no warranty expressed + * or implied. Any use is at your own risk. + * + * Permission to use or copy this software for any purpose is hereby granted + * without fee, provided the above notices are retained on all copies. + * Permission to modify the code and to distribute modified code is granted, + * provided the above notices are retained, and a notice that the code was + * modified is included with the above copyright notice. + * + */ +#include "stlport_prefix.h" + + +// Trigonometric and hyperbolic functions for complex, +// complex, and complex +#include +#include +#include + +_STLP_BEGIN_NAMESPACE + + +//---------------------------------------------------------------------- +// helpers +#if defined (__sgi) + static const union { unsigned int i; float f; } float_ulimit = { 0x42b2d4fc }; + static const float float_limit = float_ulimit.f; + static union { + struct { unsigned int h; unsigned int l; } w; + double d; + } double_ulimit = { 0x408633ce, 0x8fb9f87d }; + static const double double_limit = double_ulimit.d; + static union { + struct { unsigned int h[2]; unsigned int l[2]; } w; + long double ld; + } ldouble_ulimit = {0x408633ce, 0x8fb9f87e, 0xbd23b659, 0x4e9bd8b1}; +# if !defined (_STLP_NO_LONG_DOUBLE) + static const long double ldouble_limit = ldouble_ulimit.ld; +# endif +#else +# if defined (M_LN2) && defined (FLT_MAX_EXP) + static const float float_limit = float(M_LN2 * FLT_MAX_EXP); + static const double double_limit = M_LN2 * DBL_MAX_EXP; +# else + static const float float_limit = ::log(FLT_MAX); + static const double double_limit = ::log(DBL_MAX); +# endif +# if !defined (_STLP_NO_LONG_DOUBLE) +# if defined (M_LN2l) + static const long double ldouble_limit = M_LN2l * LDBL_MAX_EXP; +# else + static const long double ldouble_limit = ::log(LDBL_MAX); +# endif +# endif +#endif + + +//---------------------------------------------------------------------- +// sin +template +static complex<_Tp> sinT(const complex<_Tp>& z) { + return complex<_Tp>(::sin(z._M_re) * ::cosh(z._M_im), + ::cos(z._M_re) * ::sinh(z._M_im)); +} + +_STLP_DECLSPEC complex _STLP_CALL sin(const complex& z) +{ return sinT(z); } + +_STLP_DECLSPEC complex _STLP_CALL sin(const complex& z) +{ return sinT(z); } + +#if !defined (_STLP_NO_LONG_DOUBLE) +_STLP_DECLSPEC complex _STLP_CALL sin(const complex& z) +{ return sinT(z); } +#endif + +//---------------------------------------------------------------------- +// cos +template +static complex<_Tp> cosT(const complex<_Tp>& z) { + return complex<_Tp>(::cos(z._M_re) * ::cosh(z._M_im), + -::sin(z._M_re) * ::sinh(z._M_im)); +} + +_STLP_DECLSPEC complex _STLP_CALL cos(const complex& z) +{ return cosT(z); } + +_STLP_DECLSPEC complex _STLP_CALL cos(const complex& z) +{ return cosT(z); } + +#if !defined (_STLP_NO_LONG_DOUBLE) +_STLP_DECLSPEC complex _STLP_CALL cos(const complex& z) +{ return cosT(z); } +#endif + +//---------------------------------------------------------------------- +// tan +template +static complex<_Tp> tanT(const complex<_Tp>& z, const _Tp& Tp_limit) { + _Tp re2 = 2.f * z._M_re; + _Tp im2 = 2.f * z._M_im; + + if (::abs(im2) > Tp_limit) + return complex<_Tp>(0.f, (im2 > 0 ? 1.f : -1.f)); + else { + _Tp den = ::cos(re2) + ::cosh(im2); + return complex<_Tp>(::sin(re2) / den, ::sinh(im2) / den); + } +} + +_STLP_DECLSPEC complex _STLP_CALL tan(const complex& z) +{ return tanT(z, float_limit); } + +_STLP_DECLSPEC complex _STLP_CALL tan(const complex& z) +{ return tanT(z, double_limit); } + +#if !defined (_STLP_NO_LONG_DOUBLE) +_STLP_DECLSPEC complex _STLP_CALL tan(const complex& z) +{ return tanT(z, ldouble_limit); } +#endif + +//---------------------------------------------------------------------- +// sinh +template +static complex<_Tp> sinhT(const complex<_Tp>& z) { + return complex<_Tp>(::sinh(z._M_re) * ::cos(z._M_im), + ::cosh(z._M_re) * ::sin(z._M_im)); +} + +_STLP_DECLSPEC complex _STLP_CALL sinh(const complex& z) +{ return sinhT(z); } + +_STLP_DECLSPEC complex _STLP_CALL sinh(const complex& z) +{ return sinhT(z); } + +#if !defined (_STLP_NO_LONG_DOUBLE) +_STLP_DECLSPEC complex _STLP_CALL sinh(const complex& z) +{ return sinhT(z); } +#endif + +//---------------------------------------------------------------------- +// cosh +template +static complex<_Tp> coshT(const complex<_Tp>& z) { + return complex<_Tp>(::cosh(z._M_re) * ::cos(z._M_im), + ::sinh(z._M_re) * ::sin(z._M_im)); +} + +_STLP_DECLSPEC complex _STLP_CALL cosh(const complex& z) +{ return coshT(z); } + +_STLP_DECLSPEC complex _STLP_CALL cosh(const complex& z) +{ return coshT(z); } + +#if !defined (_STLP_NO_LONG_DOUBLE) +_STLP_DECLSPEC complex _STLP_CALL cosh(const complex& z) +{ return coshT(z); } +#endif + +//---------------------------------------------------------------------- +// tanh +template +static complex<_Tp> tanhT(const complex<_Tp>& z, const _Tp& Tp_limit) { + _Tp re2 = 2.f * z._M_re; + _Tp im2 = 2.f * z._M_im; + if (::abs(re2) > Tp_limit) + return complex<_Tp>((re2 > 0 ? 1.f : -1.f), 0.f); + else { + _Tp den = ::cosh(re2) + ::cos(im2); + return complex<_Tp>(::sinh(re2) / den, ::sin(im2) / den); + } +} + +_STLP_DECLSPEC complex _STLP_CALL tanh(const complex& z) +{ return tanhT(z, float_limit); } + +_STLP_DECLSPEC complex _STLP_CALL tanh(const complex& z) +{ return tanhT(z, double_limit); } + +#if !defined (_STLP_NO_LONG_DOUBLE) +_STLP_DECLSPEC complex _STLP_CALL tanh(const complex& z) +{ return tanhT(z, ldouble_limit); } +#endif + +_STLP_END_NAMESPACE