Merge pull request #5775 from wachi35676/fix/libc-lgamma-tiny-arguments

fix(libc): keep lgamma finite for subnormal arguments on Windows
This commit is contained in:
Adrià authored and GitHub committed 2026-10-15 18:36:22 +02:00
commit ec1193dc39
2 files changed
+13 -1

No files matched your search

+5 -1
View File
@@ -302,7 +302,11 @@ float APS5_VABI log1pf_nid_postfix(float x) { return std::log1p(x); }
double APS5_VABI expm1_nid_postfix(double x) { return std::expm1(x); }
float APS5_VABI expm1f_nid_postfix(float x) { return std::expm1(x); }
float APS5_VABI erff_nid_postfix(float x) { return std::erf(x); }
double APS5_VABI lgamma_nid_postfix(double x) { return std::lgamma(x); }
double APS5_VABI lgamma_nid_postfix(double x) {
const std::uint64_t magnitude = std::bit_cast<std::uint64_t>(x) & 0x7fffffffffffffffull;
if (magnitude != 0 && magnitude < 0x3c70000000000000ull) return -std::log(std::fabs(x));
return std::lgamma(x);
}
float APS5_VABI sinf_nid_postfix(float x) { return std::sin(x); }
float APS5_VABI cosf_nid_postfix(float x) { return std::cos(x); }
+8
View File
@@ -924,6 +924,14 @@ int main() {
Require(lgamma_nid_postfix(1.) == 0. && lgamma_nid_postfix(2.) == 0. && std::isinf(lgamma_nid_postfix(0.)));
Require(std::abs(lgamma_nid_postfix(0.5) - 0.5723649429247001) < 1e-15 && std::abs(lgamma_nid_postfix(10.) - 12.801827480081469) < 1e-13);
Require(std::abs(lgamma_nid_postfix(-0.5) - 1.2655121234846454) < 1e-15);
for (const double sign : {1.0, -1.0}) {
std::feclearexcept(FE_ALL_EXCEPT);
Require(std::abs(lgamma_nid_postfix(sign * std::numeric_limits<double>::denorm_min()) - 744.44007192138122) < 1e-12);
Require(std::abs(lgamma_nid_postfix(sign * 0x1p-1025) - 710.47586007394398) < 1e-12);
Require(std::abs(lgamma_nid_postfix(sign * 0x1p-1022) - 708.39641853226408) < 1e-12);
Require(std::abs(lgamma_nid_postfix(sign * 0x1p-57) - 39.509389291916882) < 1e-13);
Require(std::fetestexcept(FE_OVERFLOW | FE_DIVBYZERO | FE_INVALID) == 0);
}
Require(llroundl_nid_postfix(2.5L) == 3 && llroundl_nid_postfix(-2.5L) == -3 && llroundl_nid_postfix(0.49999999999999999L) == 0);
Require(llroundl_nid_postfix(9007199254740993.0L) == 9007199254740993LL && llroundl_nid_postfix(-1e30L) == INT64_MIN);
for (const int mode : {FE_TONEAREST, FE_DOWNWARD, FE_UPWARD, FE_TOWARDZERO}) {