cosh.c 764 B

12345678910111213141516171819202122232425262728293031323334353637383940
  1. #include "libm.h"
  2. /* cosh(x) = (exp(x) + 1/exp(x))/2
  3. * = 1 + 0.5*(exp(x)-1)*(exp(x)-1)/exp(x)
  4. * = 1 + x*x/2 + o(x^4)
  5. */
  6. double cosh(double x)
  7. {
  8. union {double f; uint64_t i;} u = {.f = x};
  9. uint32_t w;
  10. double t;
  11. /* |x| */
  12. u.i &= (uint64_t)-1/2;
  13. x = u.f;
  14. w = u.i >> 32;
  15. /* |x| < log(2) */
  16. if (w < 0x3fe62e42) {
  17. if (w < 0x3ff00000 - (26<<20)) {
  18. /* raise inexact if x!=0 */
  19. FORCE_EVAL(x + 0x1p120f);
  20. return 1;
  21. }
  22. t = expm1(x);
  23. return 1 + t*t/(2*(1+t));
  24. }
  25. /* |x| < log(DBL_MAX) */
  26. if (w < 0x40862e42) {
  27. t = exp(x);
  28. /* note: if x>log(0x1p26) then the 1/t is not needed */
  29. return 0.5*(t + 1/t);
  30. }
  31. /* |x| > log(DBL_MAX) or nan */
  32. /* note: the result is stored to handle overflow */
  33. t = __expo2(x);
  34. return t;
  35. }