diff --git a/include/boost/math/distributions/detail/inv_discrete_quantile.hpp b/include/boost/math/distributions/detail/inv_discrete_quantile.hpp index 25216e88f6..7ded3d39ad 100644 --- a/include/boost/math/distributions/detail/inv_discrete_quantile.hpp +++ b/include/boost/math/distributions/detail/inv_discrete_quantile.hpp @@ -302,15 +302,13 @@ inline typename Dist::value_type round_to_floor(const Dist& d, typename Dist::va // while(result != 0) { - cc = result - 1; + cc = floor(float_prior(result)); if(cc < support(d).first) break; pp = c ? cdf(complement(d, cc)) : cdf(d, cc); - if(pp == p) - result = cc; - else if(c ? pp > p : pp < p) + if(c ? pp > p : pp < p) break; - result -= 1; + result = cc; } return result; @@ -336,15 +334,13 @@ inline typename Dist::value_type round_to_ceil(const Dist& d, typename Dist::val // while(true) { - cc = result + 1; + cc = ceil(float_next(result)); if(cc > support(d).second) break; pp = c ? cdf(complement(d, cc)) : cdf(d, cc); - if(pp == p) - result = cc; - else if(c ? pp < p : pp > p) + if(c ? pp < p : pp > p) break; - result += 1; + result = cc; } return result; diff --git a/test/test_binomial.cpp b/test/test_binomial.cpp index fa50da7f5a..34baeaa6be 100644 --- a/test/test_binomial.cpp +++ b/test/test_binomial.cpp @@ -716,6 +716,18 @@ void test_spots(RealType T) check_out_of_range >(1, 1); // (All) valid constructor parameter values. + // TODO: Generic ibeta_power_terms has accuracy issue when long + // double is not precise enough, causing overflow in this case. + if(!std::is_same::value || + sizeof(boost::math::concepts::real_concept_base_type) > 8) + { + using namespace boost::math::policies; + typedef policy > Policy; + binomial_distribution dist(9079765771874083840, 0.561815); + // Accuracy is not too important here; the main purpose is to + // make sure it is not stuck. + BOOST_CHECK_CLOSE(quantile(dist, 0.0365346), 5101148604445670400, 1e12); + } } // template void test_spots(RealType)