home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c065 / 2.ddi / MATH.ZIP / TANH.CAS < prev    next >
Encoding:
Text File  |  1990-06-07  |  3.0 KB  |  132 lines

  1. /*------------------------------------------------------------------------
  2.  * filename - tanh.cas
  3.  *
  4.  * function(s)
  5.  *        tanh - hyperbolic tangent function
  6.  *-----------------------------------------------------------------------*/
  7.  
  8. /*[]------------------------------------------------------------[]*/
  9. /*|                                                              |*/
  10. /*|     Turbo C Run Time Library - Version 3.0                   |*/
  11. /*|                                                              |*/
  12. /*|                                                              |*/
  13. /*|     Copyright (c) 1987, 1990 by Borland International        |*/
  14. /*|     All Rights Reserved.                                     |*/
  15. /*|                                                              |*/
  16. /*[]------------------------------------------------------------[]*/
  17.  
  18.  
  19. #pragma inline
  20. #include <asmrules.h>
  21.  
  22. #include <_math.h>
  23. #include <math.h>
  24.  
  25.  
  26. /*--------------------------------------------------------------------------*
  27.  
  28. Name        tanh - hyperbolic tangent function
  29.  
  30. Usage        double tanh(double x);
  31.  
  32. Prototype in    math.h
  33.  
  34. Description    tanh calculates the hyperbolic tangent of the input.
  35.  
  36. Return value    tanh returns the hyperbolic tangent of the input value.
  37.         For large arguments (magnitude greater than 32) the result
  38.         will be +1.0 or -1.0.
  39.  
  40. *---------------------------------------------------------------------------*/
  41.  
  42. /*
  43. Algorithm.
  44.  
  45. The usual formula is:
  46.     tanh(x) = (exp(x) - exp(-x))/(exp(x) + exp(-x))/
  47. but there is a loss of precision in using this formula directly near 0.
  48.  
  49. Since tanh(-x) = -tanh(x), compute tanh(|x|) and adjust the sign later.
  50.  
  51. If 0 <= x < 2^-33, return x.
  52.  
  53. If x >= 32 return 1.
  54.  
  55. If x >= .17325, use
  56.     y = exp(x)
  57.     tanh(x) = (y - 1/y)/(y + 1/y)
  58.  
  59. If 2^-33 <= x < .17325, use
  60.     y = exp(2x) - 1
  61.     sinh(x) = y/(2 + y)
  62. where special chip functions are used to get exp(2x)-1 accurately.
  63.  
  64. */
  65.  
  66. #pragma warn -rvl
  67. double    tanh (double  x)
  68. {
  69. asm    FLD    DOUBLE (x)
  70. asm    sub    dh, dh
  71. asm    mov    cx, x [6]
  72. asm    shl    cx, 1
  73. asm    rcr    dh, 1            /* DH = sign    */
  74. asm    cmp    cx, 8080h
  75. asm    FABS
  76. asm    ja    tanh_extreme
  77.  
  78. asm    cmp    cx, 7F8Ch
  79. asm    jb    tanh_small
  80.  
  81. asm    _FAST_    (_FEXP_)        /* Exp (x)    */
  82. asm    FLD1
  83. asm    FDIV    st, st(1)        /* Exp (-x)    */
  84.  
  85. /*
  86.   tanh = sinh / cosh = (exp(x) - exp(-x)) / (exp(x) + exp(-x))
  87. */
  88. asm    FLD    st(1)
  89. asm    FSUB    st, st(1)
  90. asm    FXCH
  91. asm    FADD    st, st(2)
  92. asm    FDIVP    st(1), st
  93. asm    FSTP    st(1)
  94.  
  95. tanh_end:
  96. asm    or    dh, dh
  97. asm    jns    tanh_end2
  98. asm    FCHS
  99. tanh_end2:
  100.     return;
  101.  
  102. /*
  103.   tanh is asymptotic to -1 for negative arguments and +1 for positives.
  104.   It approaches very fast, with exponentially increasing accuracy,
  105.   so it is 1.0 for IEEE accuracy when |x| > 23.
  106. */
  107. tanh_extreme:
  108. asm    FSTP    st(0)        /* pop stack    */
  109. asm    FLD1
  110.     goto tanh_end;
  111.  
  112. tanh_small:
  113. asm    cmp    cx, 7BC0h
  114. asm    jb    tanh_end
  115. asm    FLD1
  116. asm    FXCH
  117. asm    FSCALE
  118.  
  119. asm    FLDL2E
  120. asm    FMUL
  121. asm    F2XM1
  122. /* TOS = y = exp(2x) - 1 */
  123. asm    FXCH
  124. asm    FLD1
  125. asm    FADD
  126. asm    FADD    st(0),st(1)
  127. /* stack = 2+y,y */
  128. asm    FDIV
  129.     goto tanh_end;
  130. }
  131. #pragma warn .rvl
  132.