From 2b94b63ebcc773620fa7ef40cb1ae34bac2e6348 Mon Sep 17 00:00:00 2001 From: Lucas Chollet Date: Wed, 23 Sep 2026 10:25:54 +0200 Subject: [PATCH] LibC: Handle edge cases correctly in erf --- Tests/LibC/TestMath.cpp | 11 +++++++++++ Userland/Libraries/LibC/math.cpp | 12 ++++++++++++ 2 files changed, 23 insertions(+) diff --git a/Tests/LibC/TestMath.cpp b/Tests/LibC/TestMath.cpp index 5953c8d4bca..aaf7e09f5ab 100644 --- a/Tests/LibC/TestMath.cpp +++ b/Tests/LibC/TestMath.cpp @@ -508,3 +508,14 @@ TEST_CASE(exp) EXPECT_EQ(exp(AK::Infinity), AK::Infinity); } + +TEST_CASE(erf) +{ + EXPECT(isnan(erf(AK::NaN))); + + EXPECT_EQ(erf(0.0), 0.0); + EXPECT(signbit(erf(-0.0))); + + EXPECT_EQ(erf(-AK::Infinity), -1.); + EXPECT_EQ(erf(+AK::Infinity), +1.); +} diff --git a/Userland/Libraries/LibC/math.cpp b/Userland/Libraries/LibC/math.cpp index 276774210c0..b47b25ae898 100644 --- a/Userland/Libraries/LibC/math.cpp +++ b/Userland/Libraries/LibC/math.cpp @@ -342,6 +342,18 @@ static T internal_remquo(T x, T y, int* quo) template static T internal_erf(T x) { + // If x is NaN, a NaN shall be returned. + if (isnan(x)) + return AK::NaN; + + // If x is ±0, ±0 shall be returned. + if (x == 0) + return x; + + // If x is ±Inf, ±1 shall be returned. + if (isinf(x)) + return AK::copysign(1., x); + // algorithm taken from Abramowitz and Stegun (no. 26.2.17) T t = 1 / (1 + 0.47047l * AK::fabs(x)); T poly = t * (0.3480242l + t * (-0.958798l + t * 0.7478556l));