atanhq.c 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. /* s_atanhl.c -- long double version of s_atan.c.
  2. * Conversion to long double by Ulrich Drepper,
  3. * Cygnus Support, drepper@cygnus.com.
  4. */
  5. /*
  6. * ====================================================
  7. * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
  8. *
  9. * Developed at SunPro, a Sun Microsystems, Inc. business.
  10. * Permission to use, copy, modify, and distribute this
  11. * software is freely granted, provided that this notice
  12. * is preserved.
  13. * ====================================================
  14. */
  15. /* atanhq(x)
  16. * Method :
  17. * 1.Reduced x to positive by atanh(-x) = -atanh(x)
  18. * 2.For x>=0.5
  19. * 1 2x x
  20. * atanhl(x) = --- * log(1 + -------) = 0.5 * log1p(2 * --------)
  21. * 2 1 - x 1 - x
  22. *
  23. * For x<0.5
  24. * atanhl(x) = 0.5*log1pq(2x+2x*x/(1-x))
  25. *
  26. * Special cases:
  27. * atanhl(x) is NaN if |x| > 1 with signal;
  28. * atanhl(NaN) is that NaN with no signal;
  29. * atanhl(+-1) is +-INF with signal.
  30. *
  31. */
  32. #include "quadmath-imp.h"
  33. static const __float128 one = 1, huge = 1e4900Q;
  34. static const __float128 zero = 0;
  35. __float128
  36. atanhq(__float128 x)
  37. {
  38. __float128 t;
  39. uint32_t jx, ix;
  40. ieee854_float128 u;
  41. u.value = x;
  42. jx = u.words32.w0;
  43. ix = jx & 0x7fffffff;
  44. u.words32.w0 = ix;
  45. if (ix >= 0x3fff0000) /* |x| >= 1.0 or infinity or NaN */
  46. {
  47. if (u.value == one)
  48. return x/zero;
  49. else
  50. return (x-x)/(x-x);
  51. }
  52. if(ix<0x3fc60000 && (huge+x)>zero) /* x < 2^-57 */
  53. {
  54. math_check_force_underflow (x);
  55. return x;
  56. }
  57. if(ix<0x3ffe0000) { /* x < 0.5 */
  58. t = u.value+u.value;
  59. t = 0.5*log1pq(t+t*u.value/(one-u.value));
  60. } else
  61. t = 0.5*log1pq((u.value+u.value)/(one-u.value));
  62. if(jx & 0x80000000) return -t; else return t;
  63. }