From efe4845c564f0820df9d421c27223d1652d5fc35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mi=C8=9Bca=20Dumitru?= Date: Sun, 7 Mar 2021 23:47:07 +0200 Subject: [PATCH] LibM: Implement more rounding functions This patch implements the entire rint family, while taking into account the current rounding mode, and implements ceil, round, trunc, and floor for types which they weren't before. --- Userland/Libraries/LibM/math.cpp | 77 +++++++++++++++++++++++++++++--- Userland/Libraries/LibM/math.h | 12 +++++ 2 files changed, 83 insertions(+), 6 deletions(-) diff --git a/Userland/Libraries/LibM/math.cpp b/Userland/Libraries/LibM/math.cpp index e0cd0a8a1a..068dfb7d88 100644 --- a/Userland/Libraries/LibM/math.cpp +++ b/Userland/Libraries/LibM/math.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -61,10 +62,10 @@ template constexpr size_t product_odd() { return value * product_odd(); } enum class RoundingMode { - ToZero, - Up, - Down, - ToEven + ToZero = FE_TOWARDZERO, + Up = FE_UPWARD, + Down = FE_DOWNWARD, + ToEven = FE_TONEAREST }; template @@ -307,6 +308,16 @@ double trunc(double x) NOEXCEPT return internal_to_integer(x, RoundingMode::ToZero); } +float truncf(float x) NOEXCEPT +{ + return internal_to_integer(x, RoundingMode::ToZero); +} + +long double truncl(long double x) NOEXCEPT +{ + return internal_to_integer(x, RoundingMode::ToZero); +} + double cos(double angle) NOEXCEPT { return sin(angle + M_PI_2); @@ -691,6 +702,11 @@ float roundf(float value) NOEXCEPT return internal_to_integer(value, RoundingMode::ToEven); } +long double roundl(long double value) NOEXCEPT +{ + return internal_to_integer(value, RoundingMode::ToEven); +} + float floorf(float value) NOEXCEPT { return internal_to_integer(value, RoundingMode::Down); @@ -701,10 +717,54 @@ double floor(double value) NOEXCEPT return internal_to_integer(value, RoundingMode::Down); } +long double floorl(long double value) NOEXCEPT +{ + return internal_to_integer(value, RoundingMode::Down); +} + +long double rintl(long double value) NOEXCEPT +{ + return internal_to_integer(value, RoundingMode { fegetround() }); +} + double rint(double value) NOEXCEPT { - // This should be the current rounding mode - return internal_to_integer(value, RoundingMode::ToEven); + return internal_to_integer(value, RoundingMode { fegetround() }); +} + +float rintf(float value) NOEXCEPT +{ + return internal_to_integer(value, RoundingMode { fegetround() }); +} + +long lrintl(long double value) NOEXCEPT +{ + return (long)internal_to_integer(value, RoundingMode { fegetround() }); +} + +long lrint(double value) NOEXCEPT +{ + return (long)internal_to_integer(value, RoundingMode { fegetround() }); +} + +long lrintf(float value) NOEXCEPT +{ + return (long)internal_to_integer(value, RoundingMode { fegetround() }); +} + +long long llrintl(long double value) NOEXCEPT +{ + return (long long)internal_to_integer(value, RoundingMode { fegetround() }); +} + +long long llrint(double value) NOEXCEPT +{ + return (long long)internal_to_integer(value, RoundingMode { fegetround() }); +} + +long long llrintf(float value) NOEXCEPT +{ + return (long long)internal_to_integer(value, RoundingMode { fegetround() }); } float ceilf(float value) NOEXCEPT @@ -717,6 +777,11 @@ double ceil(double value) NOEXCEPT return internal_to_integer(value, RoundingMode::Up); } +long double ceill(long double value) NOEXCEPT +{ + return internal_to_integer(value, RoundingMode::Up); +} + double modf(double x, double* intpart) NOEXCEPT { double integer_part = internal_to_integer(x, RoundingMode::ToZero); diff --git a/Userland/Libraries/LibM/math.h b/Userland/Libraries/LibM/math.h index db6b7373d9..5f769fbc2d 100644 --- a/Userland/Libraries/LibM/math.h +++ b/Userland/Libraries/LibM/math.h @@ -99,12 +99,24 @@ double tanh(double) NOEXCEPT; float tanhf(float) NOEXCEPT; double ceil(double) NOEXCEPT; float ceilf(float) NOEXCEPT; +long double ceill(long double) NOEXCEPT; double floor(double) NOEXCEPT; float floorf(float) NOEXCEPT; +long double floorl(long double) NOEXCEPT; double trunc(double) NOEXCEPT; float truncf(float) NOEXCEPT; +long double truncl(long double) NOEXCEPT; double round(double) NOEXCEPT; float roundf(float) NOEXCEPT; +long double roundl(long double) NOEXCEPT; +double rint(double) NOEXCEPT; +float rintf(float) NOEXCEPT; +long lrintl(long double) NOEXCEPT; +long lrint(double) NOEXCEPT; +long lrintf(float) NOEXCEPT; +long long llrintl(long double) NOEXCEPT; +long long llrint(double) NOEXCEPT; +long long llrintf(float) NOEXCEPT; double fabs(double) NOEXCEPT; float fabsf(float) NOEXCEPT; double fmod(double, double) NOEXCEPT;