home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / stlpt453.zip / STLport-4.5.3 / src / complex_trig.cpp < prev    next >
C/C++ Source or Header  |  2002-01-18  |  7KB  |  219 lines

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