s_asinh.c 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. /* @(#)s_asinh.c 5.1 93/09/24 */
  2. /*
  3. * ====================================================
  4. * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
  5. *
  6. * Developed at SunPro, a Sun Microsystems, Inc. business.
  7. * Permission to use, copy, modify, and distribute this
  8. * software is freely granted, provided that this notice
  9. * is preserved.
  10. * ====================================================
  11. */
  12. #if defined(LIBM_SCCS) && !defined(lint)
  13. static char rcsid[] = "$NetBSD: s_asinh.c,v 1.9 1995/05/12 04:57:37 jtc Exp $";
  14. #endif
  15. /* asinh(x)
  16. * Method :
  17. * Based on
  18. * asinh(x) = sign(x) * log [ |x| + sqrt(x*x+1) ]
  19. * we have
  20. * asinh(x) := x if 1+x*x=1,
  21. * := sign(x)*(log(x)+ln2)) for large |x|, else
  22. * := sign(x)*log(2|x|+1/(|x|+sqrt(x*x+1))) if|x|>2, else
  23. * := sign(x)*log1p(|x| + x^2/(1 + sqrt(1+x^2)))
  24. */
  25. #include "math.h"
  26. #include "math_private.h"
  27. libm_hidden_proto(log1p)
  28. libm_hidden_proto(fabs)
  29. #ifdef __STDC__
  30. static const double
  31. #else
  32. static double
  33. #endif
  34. one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
  35. ln2 = 6.93147180559945286227e-01, /* 0x3FE62E42, 0xFEFA39EF */
  36. huge= 1.00000000000000000000e+300;
  37. libm_hidden_proto(asinh)
  38. #ifdef __STDC__
  39. double asinh(double x)
  40. #else
  41. double asinh(x)
  42. double x;
  43. #endif
  44. {
  45. double t,w;
  46. int32_t hx,ix;
  47. GET_HIGH_WORD(hx,x);
  48. ix = hx&0x7fffffff;
  49. if(ix>=0x7ff00000) return x+x; /* x is inf or NaN */
  50. if(ix< 0x3e300000) { /* |x|<2**-28 */
  51. if(huge+x>one) return x; /* return x inexact except 0 */
  52. }
  53. if(ix>0x41b00000) { /* |x| > 2**28 */
  54. w = __ieee754_log(fabs(x))+ln2;
  55. } else if (ix>0x40000000) { /* 2**28 > |x| > 2.0 */
  56. t = fabs(x);
  57. w = __ieee754_log(2.0*t+one/(__ieee754_sqrt(x*x+one)+t));
  58. } else { /* 2.0 > |x| > 2**-28 */
  59. t = x*x;
  60. w =log1p(fabs(x)+t/(one+__ieee754_sqrt(one+t)));
  61. }
  62. if(hx>0) return w; else return -w;
  63. }
  64. libm_hidden_def(asinh)