1/* Complex cosine hyperbolic function for float types. 2 Copyright (C) 1997-2018 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__complex128 23ccoshq (__complex128 x) 24{ 25 __complex128 retval; 26 int rcls = fpclassifyq (__real__ x); 27 int icls = fpclassifyq (__imag__ x); 28 29 if (__glibc_likely (rcls >= QUADFP_ZERO)) 30 { 31 /* Real part is finite. */ 32 if (__glibc_likely (icls >= QUADFP_ZERO)) 33 { 34 /* Imaginary part is finite. */ 35 const int t = (int) ((FLT128_MAX_EXP - 1) * M_LN2q); 36 __float128 sinix, cosix; 37 38 if (__glibc_likely (fabsq (__imag__ x) > FLT128_MIN)) 39 { 40 sincosq (__imag__ x, &sinix, &cosix); 41 } 42 else 43 { 44 sinix = __imag__ x; 45 cosix = 1; 46 } 47 48 if (fabsq (__real__ x) > t) 49 { 50 __float128 exp_t = expq (t); 51 __float128 rx = fabsq (__real__ x); 52 if (signbitq (__real__ x)) 53 sinix = -sinix; 54 rx -= t; 55 sinix *= exp_t / 2; 56 cosix *= exp_t / 2; 57 if (rx > t) 58 { 59 rx -= t; 60 sinix *= exp_t; 61 cosix *= exp_t; 62 } 63 if (rx > t) 64 { 65 /* Overflow (original real part of x > 3t). */ 66 __real__ retval = FLT128_MAX * cosix; 67 __imag__ retval = FLT128_MAX * sinix; 68 } 69 else 70 { 71 __float128 exp_val = expq (rx); 72 __real__ retval = exp_val * cosix; 73 __imag__ retval = exp_val * sinix; 74 } 75 } 76 else 77 { 78 __real__ retval = coshq (__real__ x) * cosix; 79 __imag__ retval = sinhq (__real__ x) * sinix; 80 } 81 82 math_check_force_underflow_complex (retval); 83 } 84 else 85 { 86 __imag__ retval = __real__ x == 0 ? 0 : nanq (""); 87 __real__ retval = __imag__ x - __imag__ x; 88 } 89 } 90 else if (rcls == QUADFP_INFINITE) 91 { 92 /* Real part is infinite. */ 93 if (__glibc_likely (icls > QUADFP_ZERO)) 94 { 95 /* Imaginary part is finite. */ 96 __float128 sinix, cosix; 97 98 if (__glibc_likely (fabsq (__imag__ x) > FLT128_MIN)) 99 { 100 sincosq (__imag__ x, &sinix, &cosix); 101 } 102 else 103 { 104 sinix = __imag__ x; 105 cosix = 1; 106 } 107 108 __real__ retval = copysignq (HUGE_VALQ, cosix); 109 __imag__ retval = (copysignq (HUGE_VALQ, sinix) 110 * copysignq (1, __real__ x)); 111 } 112 else if (icls == QUADFP_ZERO) 113 { 114 /* Imaginary part is 0.0. */ 115 __real__ retval = HUGE_VALQ; 116 __imag__ retval = __imag__ x * copysignq (1, __real__ x); 117 } 118 else 119 { 120 __real__ retval = HUGE_VALQ; 121 __imag__ retval = __imag__ x - __imag__ x; 122 } 123 } 124 else 125 { 126 __real__ retval = nanq (""); 127 __imag__ retval = __imag__ x == 0 ? __imag__ x : nanq (""); 128 } 129 130 return retval; 131} 132