123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109 |
- #include "cdefs-compat.h"
- #include <complex.h>
- #include <float.h>
- #include <openlibm.h>
- #include "math_private.h"
- #ifndef __GNUC__
- #pragma STDC CX_LIMITED_RANGE ON
- #endif
- #define THRESH (LDBL_MAX / 2.414213562373095048801688724209698L)
- long double complex
- csqrtl(long double complex z)
- {
- long double complex result;
- long double a, b;
- long double t;
- int scale;
- a = creall(z);
- b = cimagl(z);
-
- if (z == 0)
- return (cpackl(0, b));
- if (isinf(b))
- return (cpackl(INFINITY, b));
- if (isnan(a)) {
- t = (b - b) / (b - b);
- return (cpackl(a, t));
- }
- if (isinf(a)) {
-
- if (signbit(a))
- return (cpackl(fabsl(b - b), copysignl(a, b)));
- else
- return (cpackl(a, copysignl(b - b, b)));
- }
-
-
- if (fabsl(a) >= THRESH || fabsl(b) >= THRESH) {
- a *= 0.25;
- b *= 0.25;
- scale = 1;
- } else {
- scale = 0;
- }
-
- if (a >= 0) {
- t = sqrtl((a + hypotl(a, b)) * 0.5);
- result = cpackl(t, b / (2 * t));
- } else {
- t = sqrtl((-a + hypotl(a, b)) * 0.5);
- result = cpackl(fabsl(b) / (2 * t), copysignl(t, b));
- }
-
- if (scale)
- return (result * 2);
- else
- return (result);
- }
|