csinq.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. /* Complex sine function for complex __float128.
  2. Copyright (C) 1997-2012 Free Software Foundation, Inc.
  3. This file is part of the GNU C Library.
  4. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
  5. The GNU C Library is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU Lesser General Public
  7. License as published by the Free Software Foundation; either
  8. version 2.1 of the License, or (at your option) any later version.
  9. The GNU C Library is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. Lesser General Public License for more details.
  13. You should have received a copy of the GNU Lesser General Public
  14. License along with the GNU C Library; if not, see
  15. <http://www.gnu.org/licenses/>. */
  16. #include "quadmath-imp.h"
  17. #ifdef HAVE_FENV_H
  18. # include <fenv.h>
  19. #endif
  20. __complex128
  21. csinq (__complex128 x)
  22. {
  23. __complex128 retval;
  24. int negate = signbitq (__real__ x);
  25. int rcls = fpclassifyq (__real__ x);
  26. int icls = fpclassifyq (__imag__ x);
  27. __real__ x = fabsq (__real__ x);
  28. if (__builtin_expect (icls >= QUADFP_ZERO, 1))
  29. {
  30. /* Imaginary part is finite. */
  31. if (__builtin_expect (rcls >= QUADFP_ZERO, 1))
  32. {
  33. /* Real part is finite. */
  34. const int t = (int) ((FLT128_MAX_EXP - 1) * M_LN2q);
  35. __float128 sinix, cosix;
  36. if (__builtin_expect (rcls != QUADFP_SUBNORMAL, 1))
  37. {
  38. sincosq (__real__ x, &sinix, &cosix);
  39. }
  40. else
  41. {
  42. sinix = __real__ x;
  43. cosix = 1.0Q;
  44. }
  45. if (fabsq (__imag__ x) > t)
  46. {
  47. __float128 exp_t = expq (t);
  48. __float128 ix = fabsq (__imag__ x);
  49. if (signbitq (__imag__ x))
  50. cosix = -cosix;
  51. ix -= t;
  52. sinix *= exp_t / 2.0Q;
  53. cosix *= exp_t / 2.0Q;
  54. if (ix > t)
  55. {
  56. ix -= t;
  57. sinix *= exp_t;
  58. cosix *= exp_t;
  59. }
  60. if (ix > t)
  61. {
  62. /* Overflow (original imaginary part of x > 3t). */
  63. __real__ retval = FLT128_MAX * sinix;
  64. __imag__ retval = FLT128_MAX * cosix;
  65. }
  66. else
  67. {
  68. __float128 exp_val = expq (ix);
  69. __real__ retval = exp_val * sinix;
  70. __imag__ retval = exp_val * cosix;
  71. }
  72. }
  73. else
  74. {
  75. __real__ retval = coshq (__imag__ x) * sinix;
  76. __imag__ retval = sinhq (__imag__ x) * cosix;
  77. }
  78. if (negate)
  79. __real__ retval = -__real__ retval;
  80. }
  81. else
  82. {
  83. if (icls == QUADFP_ZERO)
  84. {
  85. /* Imaginary part is 0.0. */
  86. __real__ retval = nanq ("");
  87. __imag__ retval = __imag__ x;
  88. #ifdef HAVE_FENV_H
  89. if (rcls == QUADFP_INFINITE)
  90. feraiseexcept (FE_INVALID);
  91. #endif
  92. }
  93. else
  94. {
  95. __real__ retval = nanq ("");
  96. __imag__ retval = nanq ("");
  97. #ifdef HAVE_FENV_H
  98. feraiseexcept (FE_INVALID);
  99. #endif
  100. }
  101. }
  102. }
  103. else if (icls == QUADFP_INFINITE)
  104. {
  105. /* Imaginary part is infinite. */
  106. if (rcls == QUADFP_ZERO)
  107. {
  108. /* Real part is 0.0. */
  109. __real__ retval = copysignq (0.0Q, negate ? -1.0Q : 1.0Q);
  110. __imag__ retval = __imag__ x;
  111. }
  112. else if (rcls > QUADFP_ZERO)
  113. {
  114. /* Real part is finite. */
  115. __float128 sinix, cosix;
  116. if (__builtin_expect (rcls != QUADFP_SUBNORMAL, 1))
  117. {
  118. sincosq (__real__ x, &sinix, &cosix);
  119. }
  120. else
  121. {
  122. sinix = __real__ x;
  123. cosix = 1.0;
  124. }
  125. __real__ retval = copysignq (HUGE_VALQ, sinix);
  126. __imag__ retval = copysignq (HUGE_VALQ, cosix);
  127. if (negate)
  128. __real__ retval = -__real__ retval;
  129. if (signbitq (__imag__ x))
  130. __imag__ retval = -__imag__ retval;
  131. }
  132. else
  133. {
  134. /* The addition raises the invalid exception. */
  135. __real__ retval = nanq ("");
  136. __imag__ retval = HUGE_VALQ;
  137. #ifdef HAVE_FENV_H
  138. if (rcls == QUADFP_INFINITE)
  139. feraiseexcept (FE_INVALID);
  140. #endif
  141. }
  142. }
  143. else
  144. {
  145. if (rcls == QUADFP_ZERO)
  146. __real__ retval = copysignq (0.0Q, negate ? -1.0Q : 1.0Q);
  147. else
  148. __real__ retval = nanq ("");
  149. __imag__ retval = nanq ("");
  150. }
  151. return retval;
  152. }