home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c082_122 / 2.ddi / MATHSRC.ZIP / SINH.CAS < prev    next >
Encoding:
Text File  |  1992-06-10  |  3.2 KB  |  136 lines

  1. /*------------------------------------------------------------------------
  2.  * filename - sinh.cas
  3.  *
  4.  * function(s)
  5.  *        sinh - hyperbolic sine function
  6.  *-----------------------------------------------------------------------*/
  7.  
  8. /*
  9.  *      C/C++ Run Time Library - Version 5.0
  10.  *
  11.  *      Copyright (c) 1987, 1992 by Borland International
  12.  *      All Rights Reserved.
  13.  *
  14.  */
  15.  
  16.  
  17. #pragma inline
  18. #include <asmrules.h>
  19.  
  20. #include <_math.h>
  21. #include <math.h>
  22. #include <errno.h>
  23. #include <stddef.h>
  24.  
  25.  
  26. /*--------------------------------------------------------------------------*
  27.  
  28. Name            sinh - hyperbolic sine function
  29.  
  30. Usage           double sinh(double x);
  31.  
  32. Prototype in    math.h
  33.  
  34. Description     sinh computes the hyperbolic sine of the input value.
  35.  
  36. Return value    sinh returns the hyperbolic sine of the input value.
  37.                 For large arguments (magnitude greater than or equal to
  38.                 710.475) the result will be an EDOM error.
  39.  
  40. *---------------------------------------------------------------------------*/
  41.  
  42. /*
  43. Algorithm.
  44.  
  45. The usual formula is:
  46.         sinh(x) = .5*(exp(x) - exp(-x))
  47. but there is a loss of precision in using this formula directly near 0.
  48.  
  49. Since sinh(-x) = -sinh(x), compute sinh(|x|) and adjust the sign later.
  50.  
  51. If 0 <= x < 2^-33, return x.
  52.  
  53. If x >= 710.475 call matherr.
  54.  
  55. If x >= .3465, use
  56.         y = exp(x)
  57.         sinh(x) = (y - 1/y)/2
  58.  
  59. If 2^-33 <= x < .3465, use
  60.         y = exp(x) - 1
  61.         sinh(x) = (y + y/(1 + y))/2
  62. where special chip functions are used to get exp(x)-1 accurately.
  63.  
  64. */
  65.  
  66. #pragma warn -rvl
  67.  
  68. double _FARFUNC sinh( double  x )
  69. {
  70. asm     FLD1
  71. asm     mov     ax, 7FFFh
  72. asm     FCHS                    /* TOS = -1.0   */
  73. asm     mov     dx, x [6]
  74. asm     and     ax, dx  /* select exponent and most signif. bits */
  75.  
  76. asm     FLD     DOUBLE (x)
  77. asm     cmp     ax, 4086h
  78. asm     jnb     sinh_tooBig     /* exp (+-710.475) is the limit */
  79.  
  80. asm     FABS
  81. asm     cmp     ax, 3FD6h
  82. asm     jb      sinh_small
  83.  
  84. sinh_justFits:
  85. #ifdef _Windows
  86.         _f87_Exp();
  87. #else
  88. asm     _FAST_  (_FEXP_)
  89. #endif
  90.  
  91. asm     FLD1
  92. asm     FDIV    st, st(1)       /* Exp (-x)     */
  93. asm     FSUBP   st(1), st
  94. asm     FSCALE                  /* sinh (x) = (exp(x) - exp(-x)) / 2    */
  95.  
  96. sinh_end:
  97. asm     FSTP    st(1)   /* discard the -1 */
  98. /* change sign if original argument was negative */
  99. asm     test    dh, 80h
  100. asm     jz      sinh_end2
  101. asm     FCHS
  102. sinh_end2:
  103.         return;
  104.  
  105. sinh_tooBig:
  106. asm     ja      sinh_over
  107. asm     cmp     W0 (x [4]), 33CEh
  108. asm     jb      sinh_justFits
  109.  
  110. sinh_over:
  111. asm     FSTP    ST(0)                   /* discard ST and ST(1) */
  112. asm     FSTP    ST(0)
  113.  
  114. #pragma warn -ret
  115.         return  _matherr (OVERFLOW, "sinh", &x, NULL,
  116.                                                 (_DX & 0x8000) ? - HUGE_VAL : HUGE_VAL);
  117. #pragma warn .ret
  118.  
  119. sinh_small:
  120. asm     cmp     ax, 3DE0h
  121. asm     jb      sinh_end                /* x tiny, return x */
  122.  
  123. asm     FLDL2E
  124. asm     FMUL
  125. asm     F2XM1
  126. /* TOS = y = exp(x) - 1 */
  127. asm     FLD1
  128. asm     FADD    st(0),st(1)
  129. /* stack = 1+y,y,-1 */
  130. asm     FDIVR   st(0),st(1)
  131. asm     FADD
  132. asm     FSCALE
  133.         goto sinh_end;
  134. }
  135. #pragma warn .rvl
  136.