mirror of
https://github.com/SerenityOS/serenity.git
synced 2026-11-07 04:29:30 -10:00
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:
1 parent
101c3c50fa
commit
d0d79c2bcb
2 files changed
+13
-4
No files matched your search
+12
-3
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user