1*627f7eb2Smrg #include "quadmath-imp.h" 2*627f7eb2Smrg #include <math.h> 3*627f7eb2Smrg #include <float.h> 4*627f7eb2Smrg 5*627f7eb2Smrg __float128 sqrtq(const __float128 x)6*627f7eb2Smrgsqrtq (const __float128 x) 7*627f7eb2Smrg { 8*627f7eb2Smrg __float128 y; 9*627f7eb2Smrg int exp; 10*627f7eb2Smrg 11*627f7eb2Smrg if (isnanq (x) || (isinfq (x) && x > 0)) 12*627f7eb2Smrg return x; 13*627f7eb2Smrg 14*627f7eb2Smrg if (x == 0) 15*627f7eb2Smrg return x; 16*627f7eb2Smrg 17*627f7eb2Smrg if (x < 0) 18*627f7eb2Smrg { 19*627f7eb2Smrg /* Return NaN with invalid signal. */ 20*627f7eb2Smrg return (x - x) / (x - x); 21*627f7eb2Smrg } 22*627f7eb2Smrg 23*627f7eb2Smrg if (x <= DBL_MAX && x >= DBL_MIN) 24*627f7eb2Smrg { 25*627f7eb2Smrg /* Use double result as starting point. */ 26*627f7eb2Smrg y = sqrt ((double) x); 27*627f7eb2Smrg 28*627f7eb2Smrg /* Two Newton iterations. */ 29*627f7eb2Smrg y -= 0.5q * (y - x / y); 30*627f7eb2Smrg y -= 0.5q * (y - x / y); 31*627f7eb2Smrg return y; 32*627f7eb2Smrg } 33*627f7eb2Smrg 34*627f7eb2Smrg #ifdef HAVE_SQRTL 35*627f7eb2Smrg { 36*627f7eb2Smrg long double xl = (long double) x; 37*627f7eb2Smrg if (xl <= LDBL_MAX && xl >= LDBL_MIN) 38*627f7eb2Smrg { 39*627f7eb2Smrg /* Use long double result as starting point. */ 40*627f7eb2Smrg y = (__float128) sqrtl (xl); 41*627f7eb2Smrg 42*627f7eb2Smrg /* One Newton iteration. */ 43*627f7eb2Smrg y -= 0.5q * (y - x / y); 44*627f7eb2Smrg return y; 45*627f7eb2Smrg } 46*627f7eb2Smrg } 47*627f7eb2Smrg #endif 48*627f7eb2Smrg 49*627f7eb2Smrg /* If we're outside of the range of C types, we have to compute 50*627f7eb2Smrg the initial guess the hard way. */ 51*627f7eb2Smrg y = frexpq (x, &exp); 52*627f7eb2Smrg if (exp % 2) 53*627f7eb2Smrg y *= 2, exp--; 54*627f7eb2Smrg 55*627f7eb2Smrg y = sqrt (y); 56*627f7eb2Smrg y = scalbnq (y, exp / 2); 57*627f7eb2Smrg 58*627f7eb2Smrg /* Two Newton iterations. */ 59*627f7eb2Smrg y -= 0.5q * (y - x / y); 60*627f7eb2Smrg y -= 0.5q * (y - x / y); 61*627f7eb2Smrg return y; 62*627f7eb2Smrg } 63*627f7eb2Smrg 64