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

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