Fix uniform_floating_point_distribution for unit ranges

This commit is contained in:
Martin Hořeňovský 2023-12-10 16:26:07 +01:00
parent ae4fe16b81
commit cb07ff9a7e
No known key found for this signature in database
GPG Key ID: DE48307B8B0D381A
3 changed files with 23 additions and 3 deletions

View File

@ -31,7 +31,7 @@ namespace Catch {
"gamma returns the largest ULP magnitude within " "gamma returns the largest ULP magnitude within "
"floating point range [a, b]. This only makes sense " "floating point range [a, b]. This only makes sense "
"for floating point types" ); "for floating point types" );
assert( a < b ); assert( a <= b );
const auto gamma_up = Catch::nextafter( a, std::numeric_limits<FloatType>::infinity() ) - a; const auto gamma_up = Catch::nextafter( a, std::numeric_limits<FloatType>::infinity() ) - a;
const auto gamma_down = b - Catch::nextafter( b, -std::numeric_limits<FloatType>::infinity() ); const auto gamma_down = b - Catch::nextafter( b, -std::numeric_limits<FloatType>::infinity() );
@ -69,7 +69,7 @@ namespace Catch {
template <typename FloatType> template <typename FloatType>
DistanceType<FloatType> DistanceType<FloatType>
count_equidistant_floats( FloatType a, FloatType b, FloatType distance ) { count_equidistant_floats( FloatType a, FloatType b, FloatType distance ) {
assert( a < b ); assert( a <= b );
// We get distance as gamma for our uniform float distribution, // We get distance as gamma for our uniform float distribution,
// so this will round perfectly. // so this will round perfectly.
const auto ag = a / distance; const auto ag = a / distance;

View File

@ -97,7 +97,7 @@ public:
m_max_steps_in_one_go( Detail::calculate_max_steps_in_one_go(m_ulp_magnitude)), m_max_steps_in_one_go( Detail::calculate_max_steps_in_one_go(m_ulp_magnitude)),
m_a_has_leq_magnitude(std::fabs(m_a) <= std::fabs(m_b)) m_a_has_leq_magnitude(std::fabs(m_a) <= std::fabs(m_b))
{ {
assert( a < b ); assert( a <= b );
} }
template <typename Generator> template <typename Generator>

View File

@ -8,6 +8,7 @@
#include <catch2/catch_test_macros.hpp> #include <catch2/catch_test_macros.hpp>
#include <catch2/catch_template_test_macros.hpp> #include <catch2/catch_template_test_macros.hpp>
#include <catch2/internal/catch_floating_point_helpers.hpp>
#include <catch2/internal/catch_random_integer_helpers.hpp> #include <catch2/internal/catch_random_integer_helpers.hpp>
#include <catch2/internal/catch_random_number_generator.hpp> #include <catch2/internal/catch_random_number_generator.hpp>
#include <catch2/internal/catch_random_seed_generation.hpp> #include <catch2/internal/catch_random_seed_generation.hpp>
@ -568,3 +569,22 @@ TEMPLATE_TEST_CASE( "uniform_floating_point_distribution is reproducible",
REQUIRE_THAT( generated, Catch::Matchers::RangeEquals( uniform_fp_test_params<TestType>::expected ) ); REQUIRE_THAT( generated, Catch::Matchers::RangeEquals( uniform_fp_test_params<TestType>::expected ) );
} }
TEMPLATE_TEST_CASE( "uniform_floating_point_distribution can handle unitary ranges",
"[rng][distribution][floating-point][approvals]",
float,
double ) {
std::random_device rd;
auto seed = rd();
CAPTURE( seed );
Catch::SimplePcg32 pcg( seed );
const auto highest = uniform_fp_test_params<TestType>::highest;
Catch::uniform_floating_point_distribution<TestType> dist( highest,
highest );
constexpr auto iters = 20;
for (int i = 0; i < iters; ++i) {
REQUIRE( Catch::Detail::directCompare( dist( pcg ), highest ) );
}
}