1 1.1 mrg /* Compute complex natural logarithm. 2 1.1 mrg Copyright (C) 1997-2018 Free Software Foundation, Inc. 3 1.1 mrg This file is part of the GNU C Library. 4 1.1 mrg Contributed by Ulrich Drepper <drepper (at) cygnus.com>, 1997. 5 1.1 mrg 6 1.1 mrg The GNU C Library is free software; you can redistribute it and/or 7 1.1 mrg modify it under the terms of the GNU Lesser General Public 8 1.1 mrg License as published by the Free Software Foundation; either 9 1.1 mrg version 2.1 of the License, or (at your option) any later version. 10 1.1 mrg 11 1.1 mrg The GNU C Library is distributed in the hope that it will be useful, 12 1.1 mrg but WITHOUT ANY WARRANTY; without even the implied warranty of 13 1.1 mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 1.1 mrg Lesser General Public License for more details. 15 1.1 mrg 16 1.1 mrg You should have received a copy of the GNU Lesser General Public 17 1.1 mrg License along with the GNU C Library; if not, see 18 1.1 mrg <http://www.gnu.org/licenses/>. */ 19 1.1 mrg 20 1.1 mrg #include "quadmath-imp.h" 21 1.1 mrg 22 1.1 mrg __complex128 23 1.1 mrg clogq (__complex128 x) 24 1.1 mrg { 25 1.1 mrg __complex128 result; 26 1.1 mrg int rcls = fpclassifyq (__real__ x); 27 1.1 mrg int icls = fpclassifyq (__imag__ x); 28 1.1 mrg 29 1.1 mrg if (__glibc_unlikely (rcls == QUADFP_ZERO && icls == QUADFP_ZERO)) 30 1.1 mrg { 31 1.1 mrg /* Real and imaginary part are 0.0. */ 32 1.1 mrg __imag__ result = signbitq (__real__ x) ? (__float128) M_PIq : 0; 33 1.1 mrg __imag__ result = copysignq (__imag__ result, __imag__ x); 34 1.1 mrg /* Yes, the following line raises an exception. */ 35 1.1 mrg __real__ result = -1 / fabsq (__real__ x); 36 1.1 mrg } 37 1.1 mrg else if (__glibc_likely (rcls != QUADFP_NAN && icls != QUADFP_NAN)) 38 1.1 mrg { 39 1.1 mrg /* Neither real nor imaginary part is NaN. */ 40 1.1 mrg __float128 absx = fabsq (__real__ x), absy = fabsq (__imag__ x); 41 1.1 mrg int scale = 0; 42 1.1 mrg 43 1.1 mrg if (absx < absy) 44 1.1 mrg { 45 1.1 mrg __float128 t = absx; 46 1.1 mrg absx = absy; 47 1.1 mrg absy = t; 48 1.1 mrg } 49 1.1 mrg 50 1.1 mrg if (absx > FLT128_MAX / 2) 51 1.1 mrg { 52 1.1 mrg scale = -1; 53 1.1 mrg absx = scalbnq (absx, scale); 54 1.1 mrg absy = (absy >= FLT128_MIN * 2 ? scalbnq (absy, scale) : 0); 55 1.1 mrg } 56 1.1 mrg else if (absx < FLT128_MIN && absy < FLT128_MIN) 57 1.1 mrg { 58 1.1 mrg scale = FLT128_MANT_DIG; 59 1.1 mrg absx = scalbnq (absx, scale); 60 1.1 mrg absy = scalbnq (absy, scale); 61 1.1 mrg } 62 1.1 mrg 63 1.1 mrg if (absx == 1 && scale == 0) 64 1.1 mrg { 65 1.1 mrg __real__ result = log1pq (absy * absy) / 2; 66 1.1 mrg math_check_force_underflow_nonneg (__real__ result); 67 1.1 mrg } 68 1.1 mrg else if (absx > 1 && absx < 2 && absy < 1 && scale == 0) 69 1.1 mrg { 70 1.1 mrg __float128 d2m1 = (absx - 1) * (absx + 1); 71 1.1 mrg if (absy >= FLT128_EPSILON) 72 1.1 mrg d2m1 += absy * absy; 73 1.1 mrg __real__ result = log1pq (d2m1) / 2; 74 1.1 mrg } 75 1.1 mrg else if (absx < 1 76 1.1 mrg && absx >= 0.5Q 77 1.1 mrg && absy < FLT128_EPSILON / 2 78 1.1 mrg && scale == 0) 79 1.1 mrg { 80 1.1 mrg __float128 d2m1 = (absx - 1) * (absx + 1); 81 1.1 mrg __real__ result = log1pq (d2m1) / 2; 82 1.1 mrg } 83 1.1 mrg else if (absx < 1 84 1.1 mrg && absx >= 0.5Q 85 1.1 mrg && scale == 0 86 1.1 mrg && absx * absx + absy * absy >= 0.5Q) 87 1.1 mrg { 88 1.1 mrg __float128 d2m1 = __quadmath_x2y2m1q (absx, absy); 89 1.1 mrg __real__ result = log1pq (d2m1) / 2; 90 1.1 mrg } 91 1.1 mrg else 92 1.1 mrg { 93 1.1 mrg __float128 d = hypotq (absx, absy); 94 1.1 mrg __real__ result = logq (d) - scale * (__float128) M_LN2q; 95 1.1 mrg } 96 1.1 mrg 97 1.1 mrg __imag__ result = atan2q (__imag__ x, __real__ x); 98 1.1 mrg } 99 1.1 mrg else 100 1.1 mrg { 101 1.1 mrg __imag__ result = nanq (""); 102 1.1 mrg if (rcls == QUADFP_INFINITE || icls == QUADFP_INFINITE) 103 1.1 mrg /* Real or imaginary part is infinite. */ 104 1.1 mrg __real__ result = HUGE_VALQ; 105 1.1 mrg else 106 1.1 mrg __real__ result = nanq (""); 107 1.1 mrg } 108 1.1 mrg 109 1.1 mrg return result; 110 1.1 mrg } 111