From 5883c255521226bba9a059d08ea2fdb705d012a1 Mon Sep 17 00:00:00 2001 From: ivica00 Date: Mon, 12 Oct 2026 22:51:11 +0200 Subject: [PATCH] feat(libc): implement nearbyint The float helper is already on main. The double helper rounds with the current mode and does not raise the inexact flag. --- core/libs/prx/libc/src/Math.cpp | 1 + core/libs/tests/GuestMath.cpp | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/core/libs/prx/libc/src/Math.cpp b/core/libs/prx/libc/src/Math.cpp index 031ac5c4e..154bfa5ae 100644 --- a/core/libs/prx/libc/src/Math.cpp +++ b/core/libs/prx/libc/src/Math.cpp @@ -183,6 +183,7 @@ int APS5_VABI __isnormalf_nid_postfix(float x) { return std::isnormal(x) ? 1 : 0 int APS5_VABI __isinff_nid_postfix(float x) { return std::isinf(x) ? 1 : 0; } float APS5_VABI nearbyintf_nid_postfix(float x) { return std::nearbyintf(x); } long double APS5_VABI nearbyintl_nid_postfix(long double x) { return std::nearbyint(x); } +double APS5_VABI nearbyint_nid_postfix(double x) { return std::nearbyint(x); } double APS5_VABI cbrt_nid_postfix(double x) { return std::cbrt(x); } double APS5_VABI asin_nid_postfix(double x) { diff --git a/core/libs/tests/GuestMath.cpp b/core/libs/tests/GuestMath.cpp index 68ddcf1ec..103c6e5bd 100644 --- a/core/libs/tests/GuestMath.cpp +++ b/core/libs/tests/GuestMath.cpp @@ -34,6 +34,7 @@ double APS5_VABI fabs_nid_postfix(double); int APS5_VABI abs_nid_postfix(int); double APS5_VABI trunc_nid_postfix(double); double APS5_VABI ceil_nid_postfix(double); +double APS5_VABI nearbyint_nid_postfix(double); double APS5_VABI fma_nid_postfix(double, double, double); long double APS5_VABI acosl_nid_postfix(long double); long double APS5_VABI asinl_nid_postfix(long double); @@ -152,6 +153,19 @@ static void CheckExactOperations() { Require(std::isnan(fma_nid_postfix(INFINITY, 0., 1.))); } +static void CheckNearbyint() { + std::feclearexcept(FE_ALL_EXCEPT); + const double zero = nearbyint_nid_postfix(0.5); + Require(zero == 0.0 && !std::signbit(zero)); + Require(nearbyint_nid_postfix(1.5) == 2.0 && nearbyint_nid_postfix(2.5) == 2.0); + Require(nearbyint_nid_postfix(2.7) == 3.0 && nearbyint_nid_postfix(-2.7) == -3.0); + Require(std::bit_cast(nearbyint_nid_postfix(-0.5)) == 0x8000000000000000ull); + Require(nearbyint_nid_postfix(0x1p53) == 0x1p53); + Require(nearbyint_nid_postfix(INFINITY) == INFINITY && nearbyint_nid_postfix(-INFINITY) == -INFINITY); + Require(std::isnan(nearbyint_nid_postfix(NAN))); + Require(std::fetestexcept(FE_INEXACT) == 0); +} + static bool ExtendedBits(long double value, std::uint64_t mantissa, std::uint16_t signExponent) { unsigned char bytes[sizeof(long double)]{}; std::memcpy(bytes, &value, sizeof(value)); @@ -709,6 +723,7 @@ int main() { CheckSquareRoot(); CheckExp2Errno(); CheckExactOperations(); + CheckNearbyint(); CheckLongDouble(); CheckNearbyintl(); CheckAsinl();