Skip to content

Commit 01dbedc

Browse files
authored
Merge pull request #1260 from boostorg/issue1247
Prevent spurious numeric underflow in ibeta_series.
2 parents 7a41ad8 + f0ef1fd commit 01dbedc

File tree

3 files changed

+31
-1
lines changed

3 files changed

+31
-1
lines changed

include/boost/math/special_functions/beta.hpp

+9-1
Original file line numberDiff line numberDiff line change
@@ -683,7 +683,15 @@ BOOST_MATH_GPU_ENABLED T ibeta_series(T a, T b, T x, T s0, const Lanczos&, bool
683683
if ((a < tools::min_value<T>()) || (b < tools::min_value<T>()))
684684
result = 0; // denorms cause overflow in the Lanzos series, result will be zero anyway
685685
else
686-
result = Lanczos::lanczos_sum_expG_scaled(c) / (Lanczos::lanczos_sum_expG_scaled(a) * Lanczos::lanczos_sum_expG_scaled(b));
686+
{
687+
T l1 = Lanczos::lanczos_sum_expG_scaled(c);
688+
T l2 = Lanczos::lanczos_sum_expG_scaled(a);
689+
T l3 = Lanczos::lanczos_sum_expG_scaled(b);
690+
if ((l2 > 1) && (l3 > 1) && (tools::max_value<T>() / l2 < l3))
691+
result = (l1 / l2) / l3;
692+
else
693+
result = l1 / (l2 * l3);
694+
}
687695

688696
if (!(boost::math::isfinite)(result))
689697
result = 0; // LCOV_EXCL_LINE we can probably never get here, covered already above?

test/Jamfile.v2

+1
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ test-suite special_fun :
190190
[ run git_issue_1175.cpp ]
191191
[ run git_issue_1194.cpp ]
192192
[ run git_issue_1255.cpp ]
193+
[ run git_issue_1247.cpp ]
193194
[ run special_functions_test.cpp /boost/test//boost_unit_test_framework ]
194195
[ run test_airy.cpp test_instances//test_instances pch_light /boost/test//boost_unit_test_framework ]
195196
[ run test_bessel_j.cpp test_instances//test_instances pch_light /boost/test//boost_unit_test_framework ]

test/git_issue_1247.cpp

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// (C) Copyright John Maddock 2025.
2+
// Use, modification and distribution are subject to the
3+
// Boost Software License, Version 1.0. (See accompanying file
4+
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5+
6+
// See also: https://godbolt.org/z/nhMsKb8Yr
7+
8+
#include <boost/math/special_functions/beta.hpp>
9+
#include <boost/core/lightweight_test.hpp>
10+
11+
int main()
12+
{
13+
float a = 1e-20;
14+
float b = 1e-21;
15+
float z = 0.5;
16+
float p = boost::math::ibeta(a, b, z, boost::math::policies::make_policy(boost::math::policies::promote_float<false>()));
17+
18+
BOOST_TEST(p != 0);
19+
20+
return boost::report_errors();
21+
}

0 commit comments

Comments
 (0)