casinhq_kernel.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. /* Return arc hyperbolic sine for a complex float type, with the
  2. imaginary part of the result possibly adjusted for use in
  3. computing other functions.
  4. Copyright (C) 1997-2018 Free Software Foundation, Inc.
  5. This file is part of the GNU C Library.
  6. The GNU C Library is free software; you can redistribute it and/or
  7. modify it under the terms of the GNU Lesser General Public
  8. License as published by the Free Software Foundation; either
  9. version 2.1 of the License, or (at your option) any later version.
  10. The GNU C Library is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. Lesser General Public License for more details.
  14. You should have received a copy of the GNU Lesser General Public
  15. License along with the GNU C Library; if not, see
  16. <http://www.gnu.org/licenses/>. */
  17. #include "quadmath-imp.h"
  18. /* Return the complex inverse hyperbolic sine of finite nonzero Z,
  19. with the imaginary part of the result subtracted from pi/2 if ADJ
  20. is nonzero. */
  21. __complex128
  22. __quadmath_kernel_casinhq (__complex128 x, int adj)
  23. {
  24. __complex128 res;
  25. __float128 rx, ix;
  26. __complex128 y;
  27. /* Avoid cancellation by reducing to the first quadrant. */
  28. rx = fabsq (__real__ x);
  29. ix = fabsq (__imag__ x);
  30. if (rx >= 1 / FLT128_EPSILON || ix >= 1 / FLT128_EPSILON)
  31. {
  32. /* For large x in the first quadrant, x + csqrt (1 + x * x)
  33. is sufficiently close to 2 * x to make no significant
  34. difference to the result; avoid possible overflow from
  35. the squaring and addition. */
  36. __real__ y = rx;
  37. __imag__ y = ix;
  38. if (adj)
  39. {
  40. __float128 t = __real__ y;
  41. __real__ y = copysignq (__imag__ y, __imag__ x);
  42. __imag__ y = t;
  43. }
  44. res = clogq (y);
  45. __real__ res += (__float128) M_LN2q;
  46. }
  47. else if (rx >= 0.5Q && ix < FLT128_EPSILON / 8)
  48. {
  49. __float128 s = hypotq (1, rx);
  50. __real__ res = logq (rx + s);
  51. if (adj)
  52. __imag__ res = atan2q (s, __imag__ x);
  53. else
  54. __imag__ res = atan2q (ix, s);
  55. }
  56. else if (rx < FLT128_EPSILON / 8 && ix >= 1.5Q)
  57. {
  58. __float128 s = sqrtq ((ix + 1) * (ix - 1));
  59. __real__ res = logq (ix + s);
  60. if (adj)
  61. __imag__ res = atan2q (rx, copysignq (s, __imag__ x));
  62. else
  63. __imag__ res = atan2q (s, rx);
  64. }
  65. else if (ix > 1 && ix < 1.5Q && rx < 0.5Q)
  66. {
  67. if (rx < FLT128_EPSILON * FLT128_EPSILON)
  68. {
  69. __float128 ix2m1 = (ix + 1) * (ix - 1);
  70. __float128 s = sqrtq (ix2m1);
  71. __real__ res = log1pq (2 * (ix2m1 + ix * s)) / 2;
  72. if (adj)
  73. __imag__ res = atan2q (rx, copysignq (s, __imag__ x));
  74. else
  75. __imag__ res = atan2q (s, rx);
  76. }
  77. else
  78. {
  79. __float128 ix2m1 = (ix + 1) * (ix - 1);
  80. __float128 rx2 = rx * rx;
  81. __float128 f = rx2 * (2 + rx2 + 2 * ix * ix);
  82. __float128 d = sqrtq (ix2m1 * ix2m1 + f);
  83. __float128 dp = d + ix2m1;
  84. __float128 dm = f / dp;
  85. __float128 r1 = sqrtq ((dm + rx2) / 2);
  86. __float128 r2 = rx * ix / r1;
  87. __real__ res = log1pq (rx2 + dp + 2 * (rx * r1 + ix * r2)) / 2;
  88. if (adj)
  89. __imag__ res = atan2q (rx + r1, copysignq (ix + r2, __imag__ x));
  90. else
  91. __imag__ res = atan2q (ix + r2, rx + r1);
  92. }
  93. }
  94. else if (ix == 1 && rx < 0.5Q)
  95. {
  96. if (rx < FLT128_EPSILON / 8)
  97. {
  98. __real__ res = log1pq (2 * (rx + sqrtq (rx))) / 2;
  99. if (adj)
  100. __imag__ res = atan2q (sqrtq (rx), copysignq (1, __imag__ x));
  101. else
  102. __imag__ res = atan2q (1, sqrtq (rx));
  103. }
  104. else
  105. {
  106. __float128 d = rx * sqrtq (4 + rx * rx);
  107. __float128 s1 = sqrtq ((d + rx * rx) / 2);
  108. __float128 s2 = sqrtq ((d - rx * rx) / 2);
  109. __real__ res = log1pq (rx * rx + d + 2 * (rx * s1 + s2)) / 2;
  110. if (adj)
  111. __imag__ res = atan2q (rx + s1, copysignq (1 + s2, __imag__ x));
  112. else
  113. __imag__ res = atan2q (1 + s2, rx + s1);
  114. }
  115. }
  116. else if (ix < 1 && rx < 0.5Q)
  117. {
  118. if (ix >= FLT128_EPSILON)
  119. {
  120. if (rx < FLT128_EPSILON * FLT128_EPSILON)
  121. {
  122. __float128 onemix2 = (1 + ix) * (1 - ix);
  123. __float128 s = sqrtq (onemix2);
  124. __real__ res = log1pq (2 * rx / s) / 2;
  125. if (adj)
  126. __imag__ res = atan2q (s, __imag__ x);
  127. else
  128. __imag__ res = atan2q (ix, s);
  129. }
  130. else
  131. {
  132. __float128 onemix2 = (1 + ix) * (1 - ix);
  133. __float128 rx2 = rx * rx;
  134. __float128 f = rx2 * (2 + rx2 + 2 * ix * ix);
  135. __float128 d = sqrtq (onemix2 * onemix2 + f);
  136. __float128 dp = d + onemix2;
  137. __float128 dm = f / dp;
  138. __float128 r1 = sqrtq ((dp + rx2) / 2);
  139. __float128 r2 = rx * ix / r1;
  140. __real__ res = log1pq (rx2 + dm + 2 * (rx * r1 + ix * r2)) / 2;
  141. if (adj)
  142. __imag__ res = atan2q (rx + r1, copysignq (ix + r2,
  143. __imag__ x));
  144. else
  145. __imag__ res = atan2q (ix + r2, rx + r1);
  146. }
  147. }
  148. else
  149. {
  150. __float128 s = hypotq (1, rx);
  151. __real__ res = log1pq (2 * rx * (rx + s)) / 2;
  152. if (adj)
  153. __imag__ res = atan2q (s, __imag__ x);
  154. else
  155. __imag__ res = atan2q (ix, s);
  156. }
  157. math_check_force_underflow_nonneg (__real__ res);
  158. }
  159. else
  160. {
  161. __real__ y = (rx - ix) * (rx + ix) + 1;
  162. __imag__ y = 2 * rx * ix;
  163. y = csqrtq (y);
  164. __real__ y += rx;
  165. __imag__ y += ix;
  166. if (adj)
  167. {
  168. __float128 t = __real__ y;
  169. __real__ y = copysignq (__imag__ y, __imag__ x);
  170. __imag__ y = t;
  171. }
  172. res = clogq (y);
  173. }
  174. /* Give results the correct sign for the original argument. */
  175. __real__ res = copysignq (__real__ res, __real__ x);
  176. __imag__ res = copysignq (__imag__ res, (adj ? 1 : __imag__ x));
  177. return res;
  178. }