diff options
| author | Kacper <kacper@mail.openlinux.dev> | 2025-12-09 19:20:15 +0100 |
|---|---|---|
| committer | Kacper <kacper@mail.openlinux.dev> | 2025-12-09 19:20:15 +0100 |
| commit | 885f5974cdf65b59415837ae97f5a14ef1350670 (patch) | |
| tree | 66ac13de29c7f4932c5fcae11773df574e4e256a /lib/libm/csqrt.c | |
| parent | 8f9e448b2ef6db7cd905540c21f3c5b190e7a1e7 (diff) | |
feat: add gzip and new headers
Diffstat (limited to 'lib/libm/csqrt.c')
| -rw-r--r-- | lib/libm/csqrt.c | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/lib/libm/csqrt.c b/lib/libm/csqrt.c new file mode 100644 index 00000000..e98cb7c6 --- /dev/null +++ b/lib/libm/csqrt.c @@ -0,0 +1,60 @@ +#include "__complex.h" + +double complex csqrt(double complex z) +{ + double complex w; + double x, y, r, t, scale; + + x = creal(z); + y = cimag(z); + if (y == 0.0) { + if (x == 0.0) { + return 0.0 + y * (double complex)I; + } else { + r = fabs(x); + r = sqrt(r); + if (x < 0.0) { + return 0.0 + r * (double complex)I; + } else { + return r + y * (double complex)I; + } + } + } + + if (x == 0.0) { + r = fabs(y); + r = sqrt(0.5 * r); + + if (y > 0) + return r + r * (double complex)I; + else + return r - r * (double complex)I; + } + + if ((fabs(x) > 4.0) || (fabs(y) > 4.0)) { + x *= 0.25; + y *= 0.25; + scale = 2.0; + } else { + x *= 1.8014398509481984e16; /* 2^54 */ + y *= 1.8014398509481984e16; + scale = 7.450580596923828125e-9; /* 2^-27 */ + } + + w = x + y * (double complex)I; + r = cabs(w); + if (x > 0) { + t = sqrt(0.5 * r + 0.5 * x); + r = scale * fabs((0.5 * y) / t); + t *= scale; + } else { + r = sqrt(0.5 * r - 0.5 * x); + t = scale * fabs((0.5 * y) / r); + r *= scale; + } + + if (y < 0) + return t - r * (double complex)I; + else + return t + r * (double complex)I; +} |
