etanh.c 954 B

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. /* xtanh.c */
  2. /* hyperbolic tangent check routine */
  3. /* this subroutine is used by the exponential function routine */
  4. /* by Stephen L. Moshier. */
  5. #include "ehead.h"
  6. void etanh( x, y )
  7. unsigned short *x, *y;
  8. {
  9. unsigned short e[NE], r[NE], j[NE], xx[NE], m2[NE];
  10. short i, n;
  11. long lj;
  12. emov( x, r );
  13. r[NE-1] &= (unsigned short )0x7fff;
  14. if( ecmp(r, eone) >= 0 )
  15. {
  16. /* tanh(x) = (exp(x) - exp(-x)) / (exp(x) + exp(-x))
  17. * Note eexp() calls xtanh, but with an argument less than (1 + log 2)/2.
  18. */
  19. eexp( r, e );
  20. ediv( e, eone, r );
  21. esub( r, e, xx );
  22. eadd( r, e, j );
  23. ediv( j, xx, y );
  24. return;
  25. }
  26. emov( etwo, m2 );
  27. eneg( m2 );
  28. n = NBITS/8; /* Number of terms to do in the continued fraction */
  29. lj = 2 * n + 1;
  30. ltoe( &lj, j );
  31. emov( j, e );
  32. emul( x, x, xx );
  33. /* continued fraction */
  34. for( i=0; i<n; i++)
  35. {
  36. ediv( e, xx, r );
  37. eadd( m2, j, j );
  38. eadd( r, j, e );
  39. }
  40. ediv( e, x, y );
  41. }