LibC: Handle edge cases correctly in erf

This commit is contained in:
Lucas Chollet committed 2026-09-24 20:33:35 +02:00
1 parent f8a9d61aa7
commit 2b94b63ebc
2 files changed
+23

No files matched your search

+11
View File
@@ -508,3 +508,14 @@ TEST_CASE(exp)
EXPECT_EQ(exp(AK::Infinity<double>), AK::Infinity<double>);
}
TEST_CASE(erf)
{
EXPECT(isnan(erf(AK::NaN<double>)));
EXPECT_EQ(erf(0.0), 0.0);
EXPECT(signbit(erf(-0.0)));
EXPECT_EQ(erf(-AK::Infinity<double>), -1.);
EXPECT_EQ(erf(+AK::Infinity<double>), +1.);
}
+12
View File
@@ -342,6 +342,18 @@ static T internal_remquo(T x, T y, int* quo)
template<FloatingPoint T>
static T internal_erf(T x)
{
// If x is NaN, a NaN shall be returned.
if (isnan(x))
return AK::NaN<T>;
// 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<T>(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));