stdcpp/src/complex_trig.cpp
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 /*
       
     2  * © Portions copyright (c) 2006-2007 Nokia Corporation.  All rights reserved.
       
     3  *
       
     4  * Copyright (c) 1999
       
     5  * Silicon Graphics Computer Systems, Inc.
       
     6  *
       
     7  * Copyright (c) 1999 
       
     8  * Boris Fomitchev
       
     9  *
       
    10  * This material is provided "as is", with absolutely no warranty expressed
       
    11  * or implied. Any use is at your own risk.
       
    12  *
       
    13  * Permission to use or copy this software for any purpose is hereby granted 
       
    14  * without fee, provided the above notices are retained on all copies.
       
    15  * Permission to modify the code and to distribute modified code is granted,
       
    16  * provided the above notices are retained, and a notice that the code was
       
    17  * modified is included with the above copyright notice.
       
    18  *
       
    19  */ 
       
    20 # include "stlport_prefix.h"
       
    21 
       
    22 
       
    23 // Trigonometric and hyperbolic functions for complex<float>, 
       
    24 // complex<double>, and complex<long double>
       
    25 
       
    26 
       
    27 #include "complex_impl.h"
       
    28 
       
    29 #include <cfloat>
       
    30 #include <cmath>
       
    31 
       
    32 #if defined(__LIBSTD_CPP_SYMBIAN32_WSD__) || defined(_STLP_LIBSTD_CPP_NO_STATIC_VAR_)
       
    33 #include "libstdcppwsd.h"
       
    34 # endif
       
    35 
       
    36 _STLP_BEGIN_NAMESPACE
       
    37 
       
    38 
       
    39 //----------------------------------------------------------------------
       
    40 // helpers
       
    41 
       
    42 #ifdef __sgi
       
    43   static const union { unsigned int i; float f; } float_ulimit = { 0x42b2d4fc };
       
    44   static const float float_limit = float_ulimit.f;
       
    45   static union {
       
    46     struct { unsigned int h; unsigned int l; } w;
       
    47     double d;
       
    48   } double_ulimit = { 0x408633ce, 0x8fb9f87d };
       
    49   static const double double_limit = double_ulimit.d;
       
    50   static union {
       
    51     struct { unsigned int h[2]; unsigned int l[2]; } w;
       
    52     long double ld;
       
    53   } ldouble_ulimit = {0x408633ce, 0x8fb9f87e, 0xbd23b659, 0x4e9bd8b1};
       
    54 # ifndef _STLP_NO_LONG_DOUBLE
       
    55   static const long double ldouble_limit = ldouble_ulimit.ld;
       
    56 # endif
       
    57 #else
       
    58 #if defined(__LIBSTD_CPP_SYMBIAN32_WSD__) || defined(_STLP_LIBSTD_CPP_NO_STATIC_VAR_)
       
    59 void complex_trig_limit_init()
       
    60 {
       
    61 	get_complex_trig_float_limit() = _STLP_LOGF(FLT_MAX);
       
    62 	get_complex_trig_double_limit() = _STLP_DO_LOG(double)(DBL_MAX);    
       
    63 } 
       
    64 # else
       
    65   static const float float_limit = _STLP_LOGF(FLT_MAX);
       
    66   static const double double_limit = _STLP_DO_LOG(double)(DBL_MAX);  
       
    67 # endif //__LIBSTD_CPP_SYMBIAN32_WSD__
       
    68 # ifndef _STLP_NO_LONG_DOUBLE
       
    69   static const long double ldouble_limit = _STLP_LOGL(LDBL_MAX);
       
    70 # endif
       
    71 #endif
       
    72 
       
    73 
       
    74 //----------------------------------------------------------------------
       
    75 // sin
       
    76 
       
    77 _STLP_EXP_DECLSPEC complex<float>  _STLP_CALL sin(const complex<float>& z) {
       
    78   return complex<float>(_STLP_SINF(z._M_re) * _STLP_COSHF(z._M_im),
       
    79                         _STLP_COSF(z._M_re) * _STLP_SINHF(z._M_im));
       
    80 }
       
    81 
       
    82 _STLP_EXP_DECLSPEC complex<double> _STLP_CALL sin(const complex<double>& z) {
       
    83   return complex<double>(_STLP_SIN(z._M_re) * _STLP_COSH(z._M_im),
       
    84                          _STLP_COS(z._M_re) * _STLP_SINH(z._M_im));
       
    85 }
       
    86 
       
    87 #ifndef _STLP_NO_LONG_DOUBLE
       
    88 _STLP_EXP_DECLSPEC complex<long double> _STLP_CALL sin(const complex<long double>& z) {
       
    89   return complex<long double>(_STLP_SINL(z._M_re) * _STLP_COSHL(z._M_im),
       
    90                               _STLP_COSL(z._M_re) * _STLP_SINHL(z._M_im));
       
    91 }
       
    92 #endif
       
    93 
       
    94 //----------------------------------------------------------------------
       
    95 // cos
       
    96 
       
    97 _STLP_EXP_DECLSPEC complex<float> _STLP_CALL cos(const complex<float>& z) {
       
    98   return complex<float>(_STLP_COSF(z._M_re) * _STLP_COSHF(z._M_im),
       
    99                         -_STLP_SINF(z._M_re) * _STLP_SINHF(z._M_im));
       
   100 }
       
   101 
       
   102 _STLP_EXP_DECLSPEC complex<double> _STLP_CALL cos(const complex<double>& z) {
       
   103   return complex<double>(_STLP_COS(z._M_re) * _STLP_COSH(z._M_im),
       
   104                         -_STLP_SIN(z._M_re) * _STLP_SINH(z._M_im));
       
   105 }
       
   106 
       
   107 #ifndef _STLP_NO_LONG_DOUBLE
       
   108 _STLP_EXP_DECLSPEC complex<long double> _STLP_CALL cos(const complex<long double>& z) {
       
   109   return complex<long double>(_STLP_COSL(z._M_re) * _STLP_COSHL(z._M_im),
       
   110                               -_STLP_SINL(z._M_re) * _STLP_SINHL(z._M_im));
       
   111 }
       
   112 # endif
       
   113 
       
   114 //----------------------------------------------------------------------
       
   115 // tan
       
   116 
       
   117 _STLP_EXP_DECLSPEC complex<float> _STLP_CALL tan(const complex<float>& z) {
       
   118   float re2 = 2.f * z._M_re;
       
   119   float im2 = 2.f * z._M_im;
       
   120 
       
   121 #if defined(__LIBSTD_CPP_SYMBIAN32_WSD__) || defined(_STLP_LIBSTD_CPP_NO_STATIC_VAR_)
       
   122   if (_STLP_ABSF(im2) > get_complex_trig_float_limit())  
       
   123 # else
       
   124   if (_STLP_ABSF(im2) > float_limit)	
       
   125 # endif  
       
   126     return complex<float>(0.f, (im2 > 0 ? 1.f : -1.f));
       
   127   else {
       
   128     float den = _STLP_COSF(re2) + _STLP_COSHF(im2);
       
   129     return complex<float>(_STLP_SINF(re2) / den, _STLP_SINHF(im2) / den);
       
   130   }
       
   131 }
       
   132 
       
   133 _STLP_EXP_DECLSPEC complex<double> _STLP_CALL tan(const complex<double>& z) {
       
   134   double re2 = 2. * z._M_re;
       
   135   double im2 = 2. * z._M_im;
       
   136 
       
   137 #if defined(__LIBSTD_CPP_SYMBIAN32_WSD__) || defined(_STLP_LIBSTD_CPP_NO_STATIC_VAR_)
       
   138   if (fabs(float(im2)) > get_complex_trig_double_limit())
       
   139 # else
       
   140   if (fabs(float(im2)) > double_limit)
       
   141 # endif  //__LIBSTD_CPP_SYMBIAN32_WSD__
       
   142     return complex<double>(0., (im2 > 0 ? 1. : -1.));
       
   143   else {
       
   144     double den = _STLP_COS(re2) + _STLP_COSH(im2);
       
   145     return complex<double>(_STLP_SIN(re2) / den, _STLP_SINH(im2) / den);
       
   146   }
       
   147 }
       
   148 
       
   149 #ifndef _STLP_NO_LONG_DOUBLE
       
   150 _STLP_EXP_DECLSPEC complex<long double> _STLP_CALL tan(const complex<long double>& z) {
       
   151   long double re2 = 2.l * z._M_re;
       
   152   long double im2 = 2.l * z._M_im;
       
   153   if (_STLP_ABSL(im2) > ldouble_limit)
       
   154     return complex<long double>(0.l, (im2 > 0 ? 1.l : -1.l));
       
   155   else {
       
   156     long double den = _STLP_COSL(re2) + _STLP_COSHL(im2);
       
   157     return complex<long double>(_STLP_SINL(re2) / den, _STLP_SINHL(im2) / den);
       
   158   }
       
   159 }
       
   160 
       
   161 # endif
       
   162 
       
   163 //----------------------------------------------------------------------
       
   164 // sinh
       
   165 
       
   166 _STLP_EXP_DECLSPEC complex<float> _STLP_CALL sinh(const complex<float>& z) {
       
   167   return complex<float>(_STLP_SINHF(z._M_re) * _STLP_COSF(z._M_im),
       
   168                         _STLP_COSHF(z._M_re) * _STLP_SINF(z._M_im));
       
   169 }
       
   170 
       
   171 _STLP_EXP_DECLSPEC complex<double> _STLP_CALL sinh(const complex<double>& z) {
       
   172   return complex<double>(_STLP_SINH(z._M_re) * _STLP_COS(z._M_im),
       
   173                          _STLP_COSH(z._M_re) * _STLP_SIN(z._M_im));
       
   174 }
       
   175 
       
   176 #ifndef _STLP_NO_LONG_DOUBLE
       
   177 _STLP_EXP_DECLSPEC complex<long double> _STLP_CALL sinh(const complex<long double>& z) {
       
   178   return complex<long double>(_STLP_SINHL(z._M_re) * _STLP_COSL(z._M_im),
       
   179                               _STLP_COSHL(z._M_re) * _STLP_SINL(z._M_im));
       
   180 }
       
   181 #endif
       
   182 
       
   183 //----------------------------------------------------------------------
       
   184 // cosh
       
   185 
       
   186 _STLP_EXP_DECLSPEC complex<float> _STLP_CALL cosh(const complex<float>& z) {
       
   187   return complex<float>(_STLP_COSHF(z._M_re) * _STLP_COSF(z._M_im),
       
   188                         _STLP_SINHF(z._M_re) * _STLP_SINF(z._M_im));
       
   189 }
       
   190 
       
   191 _STLP_EXP_DECLSPEC complex<double> _STLP_CALL cosh(const complex<double>& z) {
       
   192   return complex<double>(_STLP_COSH(z._M_re) * _STLP_COS(z._M_im),
       
   193                          _STLP_SINH(z._M_re) * _STLP_SIN(z._M_im));
       
   194 }
       
   195 
       
   196 #ifndef _STLP_NO_LONG_DOUBLE
       
   197 _STLP_EXP_DECLSPEC complex<long double> _STLP_CALL cosh(const complex<long double>& z) {
       
   198   return complex<long double>(_STLP_COSHL(z._M_re) * _STLP_COSL(z._M_im),
       
   199                               _STLP_SINHL(z._M_re) * _STLP_SINL(z._M_im));
       
   200 }
       
   201 #endif
       
   202 
       
   203 //----------------------------------------------------------------------
       
   204 // tanh
       
   205 
       
   206 _STLP_EXP_DECLSPEC complex<float> _STLP_CALL tanh(const complex<float>& z) {
       
   207   float re2 = 2.f * z._M_re;
       
   208   float im2 = 2.f * z._M_im;
       
   209 #if defined(__LIBSTD_CPP_SYMBIAN32_WSD__) || defined(_STLP_LIBSTD_CPP_NO_STATIC_VAR_)
       
   210    if (_STLP_ABSF(re2) > get_complex_trig_float_limit())
       
   211 # else
       
   212    if (_STLP_ABSF(re2) > float_limit)
       
   213 # endif  //__LIBSTD_CPP_SYMBIAN32_WSD__
       
   214     return complex<float>((re2 > 0 ? 1.f : -1.f), 0.f);
       
   215   else {
       
   216     float den = _STLP_COSHF(re2) + _STLP_COSF(im2);
       
   217     return complex<float>(_STLP_SINHF(re2) / den, _STLP_SINF(im2) / den);
       
   218   }
       
   219 }
       
   220 
       
   221 _STLP_EXP_DECLSPEC complex<double> _STLP_CALL tanh(const complex<double>& z) {
       
   222   double re2 = 2. * z._M_re;
       
   223   double im2 = 2. * z._M_im;  
       
   224  
       
   225 #if defined(__LIBSTD_CPP_SYMBIAN32_WSD__) || defined(_STLP_LIBSTD_CPP_NO_STATIC_VAR_)
       
   226   if (fabs(float(re2)) > get_complex_trig_double_limit())
       
   227 # else
       
   228   if (fabs(float(re2)) > double_limit)
       
   229 # endif //__LIBSTD_CPP_SYMBIAN32_WSD__  
       
   230     return complex<double>((re2 > 0 ? 1. : -1.), 0.);
       
   231   else {
       
   232     double den = _STLP_COSH(re2) + _STLP_COS(im2);
       
   233     return complex<double>(_STLP_SINH(re2) / den, _STLP_SIN(im2) / den);
       
   234   }
       
   235 }
       
   236 
       
   237 #ifndef _STLP_NO_LONG_DOUBLE
       
   238 _STLP_EXP_DECLSPEC complex<long double> _STLP_CALL tanh(const complex<long double>& z) {
       
   239   long double re2 = 2.l * z._M_re;
       
   240   long double im2 = 2.l * z._M_im;
       
   241   if (_STLP_ABSL(re2) > ldouble_limit)
       
   242     return complex<long double>((re2 > 0 ? 1.l : -1.l), 0.l);
       
   243   else {
       
   244     long double den = _STLP_COSHL(re2) + _STLP_COSL(im2);
       
   245     return complex<long double>(_STLP_SINHL(re2) / den, _STLP_SINL(im2) / den);
       
   246   }
       
   247 }
       
   248 #endif
       
   249 _STLP_END_NAMESPACE