From 1f5518e2c83c476d2ca9f9446d056fa43a1c539e Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Fri, 15 Mar 2024 20:03:04 +0100 Subject: [PATCH] Library: introduce functions for floating-point comparisons - rough numeric comparisons (optionally given precision) - epsilon comparison based on numeric_limits --- src/lib/test/test-helper.hpp | 38 ++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/lib/test/test-helper.hpp b/src/lib/test/test-helper.hpp index bfb31f7bb..a2673c4ec 100644 --- a/src/lib/test/test-helper.hpp +++ b/src/lib/test/test-helper.hpp @@ -41,6 +41,7 @@ #include "lib/symbol.hpp" +#include "lib/meta/trait.hpp" #include "lib/time/timevalue.hpp" #include "lib/test/transiently.hpp" #include "lib/format-obj.hpp" @@ -48,7 +49,9 @@ #include #include #include +#include #include +#include @@ -61,6 +64,41 @@ namespace test{ using lib::meta::demangleCxx; + constexpr auto ROUGH_PRECISION = pow (10, -3); + constexpr auto EPSILON_ULP = 5; + + + template + constexpr inline meta::enable_if< std::is_floating_point, + bool > + roughEQ (F val, N target, F limit =ROUGH_PRECISION) + { + REQUIRE (0 < limit); + return abs (val/target - F(1)) < limit; + } + + + template + constexpr inline meta::enable_if< std::is_floating_point, + F > + ulp (F val) + { + val = fabs (val); + const int exp = val < std::numeric_limits::min() + ? std::numeric_limits::min_exponent - 1 // fixed exponent for subnormals + : std::ilogb (val); + auto scaledUlp = std::ldexp (std::numeric_limits::epsilon(), exp); + ENSURE (F(0) < scaledUlp); + return scaledUlp; + } + + template + constexpr inline meta::enable_if< std::is_floating_point, + bool > + epsEQ (F val, N target, uint ulps =EPSILON_ULP) + { + return abs (val - target) < ulps * ulp (target); + } /** for printing sizeof().