AK/Math: Make lgamma_r's sign computation more sound

This still doesn't always produce the correct result for negative values
of x, but at least this fixes the reasoning.
This commit is contained in:
Lucas Chollet committed 2026-10-12 18:39:50 +02:00
1 parent 101c3c50fa
commit d0d79c2bcb
2 files changed
+13 -4

No files matched your search

+12 -3
View File
@@ -56,12 +56,21 @@ constexpr T lgamma(T x)
return Detail::stirling_approximation(x);
}
// The lgamma_r variant uses an out parameter to return a sign value.
// lgamma can be written as lgamma(x) = log(|Γ(x)|), the out parameter
// corresponds to the sign of Γ(x).
template<FloatingPoint T>
constexpr T lgamma_r(T x, int* sign)
{
auto result = lgamma(x);
*sign = signbit(result) ? -1 : 1;
return result;
if (x > 0) {
// ∀ x ∈ ℝ, x > 0 ⇒ Γ(x) > 0
*sign = 1;
} else {
// FIXME: Correctly compute sign's value.
*sign = -1;
}
return lgamma(x);
}
}
+1 -1
View File
@@ -346,7 +346,7 @@ TEST_CASE(gamma)
EXPECT(isnan(lgamma(NAN)));
EXPECT(isinf(lgamma(INFINITY)));
EXPECT(isinf(lgamma(-INFINITY)));
EXPECT_EQ(signgam, 1);
EXPECT_EQ(signgam, -1); // This is not specified by POSIX.
lgamma(-2.5);
EXPECT_EQ(signgam, -1);
}