From 2b48933f2984d95c5bfd46fe330fbe172613e434 Mon Sep 17 00:00:00 2001 From: Bananymous Date: Sun, 1 Jun 2025 13:47:05 +0300 Subject: [PATCH] LibC: Implement all functions from complex.h --- userspace/libraries/LibC/CMakeLists.txt | 1 + userspace/libraries/LibC/complex.cpp | 192 +++++++++++++++++++++ userspace/libraries/LibC/include/complex.h | 14 +- 3 files changed, 201 insertions(+), 6 deletions(-) create mode 100644 userspace/libraries/LibC/complex.cpp diff --git a/userspace/libraries/LibC/CMakeLists.txt b/userspace/libraries/LibC/CMakeLists.txt index 560aa5e3..27e172f3 100644 --- a/userspace/libraries/LibC/CMakeLists.txt +++ b/userspace/libraries/LibC/CMakeLists.txt @@ -1,6 +1,7 @@ set(LIBC_SOURCES arpa/inet.cpp assert.cpp + complex.cpp ctype.cpp dirent.cpp dlfcn.cpp diff --git a/userspace/libraries/LibC/complex.cpp b/userspace/libraries/LibC/complex.cpp new file mode 100644 index 00000000..cc0e766f --- /dev/null +++ b/userspace/libraries/LibC/complex.cpp @@ -0,0 +1,192 @@ +#include +#include + +#include +#include + +template struct _complex_t; +template<> struct _complex_t { using type = __complex__ float; }; +template<> struct _complex_t { using type = __complex__ double; }; +template<> struct _complex_t { using type = __complex__ long double; }; + +template +using _complex = _complex_t::type; + +template +static constexpr T _cabs(_complex z) +{ + return BAN::Math::sqrt(creal(z) * creal(z) + cimag(z) * cimag(z)); +} + +template +static constexpr T _carg(_complex z) +{ + return BAN::Math::atan2(cimag(z), creal(z)); +} + +template +static constexpr _complex _cproj(_complex z) +{ + if (!isfinite(creal(z)) || !isfinite(cimag(z))) + return INFINITY + I * copysign(0.0, cimag(z)); + return z; +} + +template +static constexpr _complex _conj(_complex z) +{ + cimag(z) = -cimag(z); + return z; +} + +template +static constexpr _complex _cexp(_complex z) +{ + T sin, cos; + BAN::Math::sincos(cimag(z), sin, cos); + return BAN::Math::exp(creal(z)) * (cos + sin * I); +} + +template +static constexpr _complex _clog(_complex z) +{ + return BAN::Math::log(_cabs(z)) + I * _carg(z); +} + +template +static constexpr _complex _csqrt(_complex z) +{ + return BAN::Math::sqrt(_cabs(z)) * _cexp(I * _carg(z) / 2); +} + +template +static constexpr _complex _csin(_complex z) +{ + return (_cexp(z * I) - _cexp(-z * I)) / 2i; +} + +template +static constexpr _complex _ccos(_complex z) +{ + return (_cexp(z * I) + _cexp(-z * I)) / 2i; +} + +template +static constexpr _complex _ctan(_complex z) +{ + const _complex exp_pos = _cexp(+I * z); + const _complex exp_neg = _cexp(-I * z); + return -I * (exp_pos - exp_neg) / (exp_pos + exp_neg); +} + +template +static constexpr _complex _cpow(_complex x, _complex y) +{ + const T ln_r = BAN::Math::log(_cabs(x)); + const T theta = _carg(x); + const T a = creal(y); + const T b = cimag(y); + return BAN::Math::exp(a * ln_r - b * theta) * _cexp(I * (a * theta + b * ln_r)); +} + +template +static constexpr _complex _casin(_complex z) +{ + return -I * _clog(_csqrt(1 - z * z) + I * z); +} + +template +static constexpr _complex _cacos(_complex z) +{ + return -I * _clog(I * _csqrt(1 - z * z) + z); +} + +template +static constexpr _complex _catan(_complex z) +{ + return -I / 2 * _clog((I - z) / (I + z)); +} + +template +static constexpr _complex _csinh(_complex z) +{ + return (_cexp(z) - _cexp(-z)) / 2; +} + +template +static constexpr _complex _ccosh(_complex z) +{ + return (_cexp(z) + _cexp(-z)) / 2; +} + +template +static constexpr _complex _ctanh(_complex z) +{ + const _complex exp2x = _cexp(2 * z); + return (exp2x - 1) / (exp2x + 1); +} + +template +static constexpr _complex _casinh(_complex z) +{ + return _clog(z + _csqrt(z * z + 1)); +} + +template +static constexpr _complex _cacosh(_complex z) +{ + return _clog(z + _csqrt(z * z - 1)); +} + +template +static constexpr _complex _catanh(_complex z) +{ + return _clog((1 + z) / (1 - z)) / 2; +} + + +#define COMPLEX_FUNCS(func) \ + float func##f(float complex a) { return _##func(a); } \ + double func(double complex a) { return _##func(a); } \ + long double func##l(long double complex a) { return _##func(a); } + +COMPLEX_FUNCS(cabs) +COMPLEX_FUNCS(carg) + +#undef COMPLEX_FUNCS + + +#define COMPLEX_FUNCS(func) \ + float complex func##f(float complex a) { return _##func(a); } \ + double complex func(double complex a) { return _##func(a); } \ + long double complex func##l(long double complex a) { return _##func(a); } + +COMPLEX_FUNCS(cproj) +COMPLEX_FUNCS(conj) +COMPLEX_FUNCS(cexp) +COMPLEX_FUNCS(ctan) +COMPLEX_FUNCS(clog) +COMPLEX_FUNCS(csin) +COMPLEX_FUNCS(ccos) +COMPLEX_FUNCS(csqrt) +COMPLEX_FUNCS(csinh) +COMPLEX_FUNCS(ccosh) +COMPLEX_FUNCS(ctanh) +COMPLEX_FUNCS(cacos) +COMPLEX_FUNCS(casin) +COMPLEX_FUNCS(catan) +COMPLEX_FUNCS(cacosh) +COMPLEX_FUNCS(casinh) +COMPLEX_FUNCS(catanh) + +#undef COMPLEX_FUNCS + + +#define COMPLEX_FUNCS(func) \ + float complex func##f(float complex a, float complex b) { return _##func(a, b); } \ + double complex func(double complex a, double complex b) { return _##func(a, b); } \ + long double complex func##l(long double complex a, long double complex b) { return _##func(a, b); } + +COMPLEX_FUNCS(cpow) + +#undef COMPLEX_FUNCS diff --git a/userspace/libraries/LibC/include/complex.h b/userspace/libraries/LibC/include/complex.h index 3fff901d..7ed28022 100644 --- a/userspace/libraries/LibC/include/complex.h +++ b/userspace/libraries/LibC/include/complex.h @@ -13,6 +13,14 @@ __BEGIN_DECLS +#define creal(complex) (__real__ (complex)) +#define crealf(complex) (__real__ (complex)) +#define creall(complex) (__real__ (complex)) + +#define cimag(complex) (__imag__ (complex)) +#define cimagf(complex) (__imag__ (complex)) +#define cimagl(complex) (__imag__ (complex)) + double cabs(double complex); float cabsf(float complex); long double cabsl(long double complex); @@ -46,9 +54,6 @@ long double complex ccosl(long double complex); double complex cexp(double complex); float complex cexpf(float complex); long double complex cexpl(long double complex); -double cimag(double complex); -float cimagf(float complex); -long double cimagl(long double complex); double complex clog(double complex); float complex clogf(float complex); long double complex clogl(long double complex); @@ -61,9 +66,6 @@ long double complex cpowl(long double complex, long double complex); double complex cproj(double complex); float complex cprojf(float complex); long double complex cprojl(long double complex); -double creal(double complex); -float crealf(float complex); -long double creall(long double complex); double complex csin(double complex); float complex csinf(float complex); double complex csinh(double complex);