Read-only mirrors. Development, issues and pull requests are on GitHub.

summaryrefslogtreecommitdiffhomepage
path: root/tests/SelfTest
diff options
context:
space:
mode:
authorMartin Hořeňovský2023-11-19 21:00:53 +0100
committerMartin Hořeňovský2023-12-10 18:44:10 +0100
commitd139b4ff7cd8823923e8616e8fef954e09e46322 (patch)
treecd0e03dde2d2b3e72911d27182355b63c6540d70 /tests/SelfTest
parentbfd9f0f5a67c0127b25ac82eb828f6ab71aaae1e (diff)
downloadcatch3-d139b4ff7cd8823923e8616e8fef954e09e46322.tar.gz
Add implementation of helpers for uniform float distribution
Specifically we add * `gamma(a, b)`, which returns the magnitude of largest 1-ULP step in range [a, b]. * `count_equidistant_float(a, b, distance)`, which returns the number of equi-distant floats in range [a, b].
Diffstat (limited to 'tests/SelfTest')
-rw-r--r--tests/SelfTest/IntrospectiveTests/FloatingPoint.tests.cpp59
1 files changed, 59 insertions, 0 deletions
diff --git a/tests/SelfTest/IntrospectiveTests/FloatingPoint.tests.cpp b/tests/SelfTest/IntrospectiveTests/FloatingPoint.tests.cpp
index 08a579c9..eaf22a44 100644
--- a/tests/SelfTest/IntrospectiveTests/FloatingPoint.tests.cpp
+++ b/tests/SelfTest/IntrospectiveTests/FloatingPoint.tests.cpp
@@ -9,7 +9,9 @@
#include <catch2/catch_test_macros.hpp>
#include <catch2/catch_template_test_macros.hpp>
#include <catch2/internal/catch_floating_point_helpers.hpp>
+#include <catch2/internal/catch_random_floating_point_helpers.hpp>
+#include <limits>
TEST_CASE("convertToBits", "[floating-point][conversion]") {
using Catch::Detail::convertToBits;
@@ -72,3 +74,60 @@ TEST_CASE("UlpDistance", "[floating-point][ulp][approvals]") {
CHECK( ulpDistance( 1.f, 2.f ) == 0x80'00'00 );
CHECK( ulpDistance( -2.f, 2.f ) == 0x80'00'00'00 );
}
+
+
+
+TEMPLATE_TEST_CASE("gamma", "[approvals][floating-point][ulp][gamma]", float, double) {
+ using Catch::Detail::gamma;
+ using Catch::Detail::directCompare;
+
+ // We need to butcher the equal tests with the directCompare helper,
+ // because the Wfloat-equal triggers in decomposer rather than here,
+ // so we cannot locally disable it. Goddamn GCC.
+ CHECK( directCompare( gamma( TestType( -1. ), TestType( 1. ) ),
+ gamma( TestType( 0.2332 ), TestType( 1.0 ) ) ) );
+ CHECK( directCompare( gamma( TestType( -2. ), TestType( 0 ) ),
+ gamma( TestType( 1. ), TestType( 1.5 ) ) ) );
+ CHECK( gamma( TestType( 0. ), TestType( 1.0 ) ) <
+ gamma( TestType( 1.0 ), TestType( 1.5 ) ) );
+ CHECK( gamma( TestType( 0 ), TestType( 1. ) ) <
+ std::numeric_limits<TestType>::epsilon() );
+ CHECK( gamma( TestType( -1. ), TestType( -0. ) ) <
+ std::numeric_limits<TestType>::epsilon() );
+ CHECK( directCompare( gamma( TestType( 1. ), TestType( 2. ) ),
+ std::numeric_limits<TestType>::epsilon() ) );
+ CHECK( directCompare( gamma( TestType( -2. ), TestType( -1. ) ),
+ std::numeric_limits<TestType>::epsilon() ) );
+}
+
+TEMPLATE_TEST_CASE("count_equidistant_floats",
+ "[approvals][floating-point][distance]",
+ float,
+ double) {
+ using Catch::Detail::count_equidistant_floats;
+ auto count_steps = []( TestType a, TestType b ) {
+ return count_equidistant_floats( a, b, Catch::Detail::gamma( a, b ) );
+ };
+
+ CHECK( count_steps( TestType( -1. ), TestType( 1. ) ) ==
+ 2 * count_steps( TestType( 0. ), TestType( 1. ) ) );
+}
+
+TEST_CASE( "count_equidistant_floats",
+ "[approvals][floating-point][distance]" ) {
+ using Catch::Detail::count_equidistant_floats;
+ auto count_floats_with_scaled_ulp = []( auto a, auto b ) {
+ return count_equidistant_floats( a, b, Catch::Detail::gamma( a, b ) );
+ };
+
+ CHECK( count_floats_with_scaled_ulp( 1., 1.5 ) == 1ull << 51 );
+ CHECK( count_floats_with_scaled_ulp( 1.25, 1.5 ) == 1ull << 50 );
+ CHECK( count_floats_with_scaled_ulp( 1.f, 1.5f ) == 1 << 22 );
+
+ STATIC_REQUIRE( std::is_same<std::uint64_t,
+ decltype( count_floats_with_scaled_ulp(
+ 0., 1. ) )>::value );
+ STATIC_REQUIRE( std::is_same<std::uint32_t,
+ decltype( count_floats_with_scaled_ulp(
+ 0.f, 1.f ) )>::value );
+}