1 | /* Complex sine hyperbole 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 | |

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 | |

11 | The GNU C Library is distributed in the hope that it will be useful, |

12 | but WITHOUT ANY WARRANTY; without even the implied warranty of |

13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |

14 | Lesser General Public License for more details. |

15 | |

16 | You should have received a copy of the GNU Lesser General Public |

17 | License along with the GNU C Library; if not, see |

18 | <http://www.gnu.org/licenses/>. */ |

19 | |

20 | #include "quadmath-imp.h" |

21 | |

22 | #ifdef HAVE_FENV_H |

23 | # include <fenv.h> |

24 | #endif |

25 | |

26 | |

27 | __complex128 |

28 | csinhq (__complex128 x) |

29 | { |

30 | __complex128 retval; |

31 | int negate = signbitq (__real__ x); |

32 | int rcls = fpclassifyq (__real__ x); |

33 | int icls = fpclassifyq (__imag__ x); |

34 | |

35 | __real__ x = fabsq (__real__ x); |

36 | |

37 | if (__builtin_expect (rcls >= QUADFP_ZERO, 1)) |

38 | { |

39 | /* Real part is finite. */ |

40 | if (__builtin_expect (icls >= QUADFP_ZERO, 1)) |

41 | { |

42 | /* Imaginary part is finite. */ |

43 | const int t = (int) ((FLT128_MAX_EXP - 1) * M_LN2q); |

44 | __float128 sinix, cosix; |

45 | |

46 | if (__builtin_expect (icls != QUADFP_SUBNORMAL, 1)) |

47 | { |

48 | sincosq (__imag__ x, &sinix, &cosix); |

49 | } |

50 | else |

51 | { |

52 | sinix = __imag__ x; |

53 | cosix = 1.0Q; |

54 | } |

55 | |

56 | if (fabsq (__real__ x) > t) |

57 | { |

58 | __float128 exp_t = expq (t); |

59 | __float128 rx = fabsq (__real__ x); |

60 | if (signbitq (__real__ x)) |

61 | cosix = -cosix; |

62 | rx -= t; |

63 | sinix *= exp_t / 2.0Q; |

64 | cosix *= exp_t / 2.0Q; |

65 | if (rx > t) |

66 | { |

67 | rx -= t; |

68 | sinix *= exp_t; |

69 | cosix *= exp_t; |

70 | } |

71 | if (rx > t) |

72 | { |

73 | /* Overflow (original real part of x > 3t). */ |

74 | __real__ retval = FLT128_MAX * cosix; |

75 | __imag__ retval = FLT128_MAX * sinix; |

76 | } |

77 | else |

78 | { |

79 | __float128 exp_val = expq (rx); |

80 | __real__ retval = exp_val * cosix; |

81 | __imag__ retval = exp_val * sinix; |

82 | } |

83 | } |

84 | else |

85 | { |

86 | __real__ retval = sinhq (__real__ x) * cosix; |

87 | __imag__ retval = coshq (__real__ x) * sinix; |

88 | } |

89 | |

90 | if (negate) |

91 | __real__ retval = -__real__ retval; |

92 | } |

93 | else |

94 | { |

95 | if (rcls == QUADFP_ZERO) |

96 | { |

97 | /* Real part is 0.0. */ |

98 | __real__ retval = copysignq (0.0Q, negate ? -1.0Q : 1.0Q); |

99 | __imag__ retval = nanq ("") + nanq ( ""); |

100 | |

101 | #ifdef HAVE_FENV_H |

102 | if (icls == QUADFP_INFINITE) |

103 | feraiseexcept (FE_INVALID); |

104 | #endif |

105 | } |

106 | else |

107 | { |

108 | __real__ retval = nanq (""); |

109 | __imag__ retval = nanq (""); |

110 | |

111 | #ifdef HAVE_FENV_H |

112 | feraiseexcept (FE_INVALID); |

113 | #endif |

114 | } |

115 | } |

116 | } |

117 | else if (rcls == QUADFP_INFINITE) |

118 | { |

119 | /* Real part is infinite. */ |

120 | if (__builtin_expect (icls > QUADFP_ZERO, 1)) |

121 | { |

122 | /* Imaginary part is finite. */ |

123 | __float128 sinix, cosix; |

124 | |

125 | if (__builtin_expect (icls != QUADFP_SUBNORMAL, 1)) |

126 | { |

127 | sincosq (__imag__ x, &sinix, &cosix); |

128 | } |

129 | else |

130 | { |

131 | sinix = __imag__ x; |

132 | cosix = 1.0; |

133 | } |

134 | |

135 | __real__ retval = copysignq (HUGE_VALQ, cosix); |

136 | __imag__ retval = copysignq (HUGE_VALQ, sinix); |

137 | |

138 | if (negate) |

139 | __real__ retval = -__real__ retval; |

140 | } |

141 | else if (icls == QUADFP_ZERO) |

142 | { |

143 | /* Imaginary part is 0.0. */ |

144 | __real__ retval = negate ? -HUGE_VALQ : HUGE_VALQ; |

145 | __imag__ retval = __imag__ x; |

146 | } |

147 | else |

148 | { |

149 | /* The addition raises the invalid exception. */ |

150 | __real__ retval = HUGE_VALQ; |

151 | __imag__ retval = nanq ("") + nanq ( ""); |

152 | |

153 | #ifdef HAVE_FENV_H |

154 | if (icls == QUADFP_INFINITE) |

155 | feraiseexcept (FE_INVALID); |

156 | #endif |

157 | } |

158 | } |

159 | else |

160 | { |

161 | __real__ retval = nanq (""); |

162 | __imag__ retval = __imag__ x == 0.0Q ? __imag__ x : nanq (""); |

163 | } |

164 | |

165 | return retval; |

166 | } |

167 |