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