Add C++11 header <cuchar>.
[official-gcc.git] / libquadmath / math / sqrtq.c
blobf63c0d1f6d2749f235a611173b5c17291a7217d7
1 #include "quadmath-imp.h"
2 #include <math.h>
3 #include <float.h>
5 __float128
6 sqrtq (const __float128 x)
8 __float128 y;
9 int exp;
11 if (isnanq (x) || (isinfq (x) && x > 0))
12 return x;
14 if (x == 0)
15 return x;
17 if (x < 0)
19 /* Return NaN with invalid signal. */
20 return (x - x) / (x - x);
23 if (x <= DBL_MAX && x >= DBL_MIN)
25 /* Use double result as starting point. */
26 y = sqrt ((double) x);
28 /* Two Newton iterations. */
29 y -= 0.5q * (y - x / y);
30 y -= 0.5q * (y - x / y);
31 return y;
34 #ifdef HAVE_SQRTL
35 if (x <= LDBL_MAX && x >= LDBL_MIN)
37 /* Use long double result as starting point. */
38 y = sqrtl ((long double) x);
40 /* One Newton iteration. */
41 y -= 0.5q * (y - x / y);
42 return y;
44 #endif
46 /* If we're outside of the range of C types, we have to compute
47 the initial guess the hard way. */
48 y = frexpq (x, &exp);
49 if (exp % 2)
50 y *= 2, exp--;
52 y = sqrt (y);
53 y = scalbnq (y, exp / 2);
55 /* Two Newton iterations. */
56 y -= 0.5q * (y - x / y);
57 y -= 0.5q * (y - x / y);
58 return y;