From 1bf439b865e42728cd93bd3a4e3b6a2fa7b673f2 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 13 Aug 2024 13:56:01 +0200 Subject: [PATCH] Use correct precision to compare --- Detectors/TPC/base/test/testTPCCalDet.cxx | 40 ++++++++++++++++++----- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/Detectors/TPC/base/test/testTPCCalDet.cxx b/Detectors/TPC/base/test/testTPCCalDet.cxx index 3fcfae6bc3a52..b93e952084396 100644 --- a/Detectors/TPC/base/test/testTPCCalDet.cxx +++ b/Detectors/TPC/base/test/testTPCCalDet.cxx @@ -28,21 +28,45 @@ namespace o2::tpc { -//templated euqality check -// for integer one would need a specialisation to check for == instead of < +// templated euqality check +// for integer one would need a specialisation to check for == instead of < template +bool isEqualAbs(T x, T y, int n = 1) +{ + // Since `epsilon()` is the gap size (ULP, unit in the last place) + // of floating-point numbers in interval [1, 2), we can scale it to + // the gap size in interval [2^e, 2^{e+1}), where `e` is the exponent + // of `x` and `y`. + + // If `x` and `y` have different gap sizes (which means they have + // different exponents), we take the smaller one. Taking the bigger + // one is also reasonable, I guess. + const T m = std::min(std::fabs(x), std::fabs(y)); + + // Subnormal numbers have fixed exponent, which is `min_exponent - 1`. + const int exp = m < std::numeric_limits::min() + ? std::numeric_limits::min_exponent - 1 + : std::ilogb(m); + + // We consider `x` and `y` equal if the difference between them is + // within `n` ULPs. + return std::fabs(x - y) <= n * std::ldexp(std::numeric_limits::epsilon(), exp); +} + +template + requires(std::integral) bool isEqualAbs(T val1, T val2) { - return std::abs(val1 - val2) < std::numeric_limits::epsilon(); + return val1 == val2; } BOOST_AUTO_TEST_CASE(CalArray_ROOTIO) { - //CalROC roc(PadSubset::ROC, 10); + // CalROC roc(PadSubset::ROC, 10); CalArray roc(PadSubset::ROC, 10); int iter = 0; - //unsigned iter=0; + // unsigned iter=0; for (auto& val : roc.getData()) { val = iter++; } @@ -51,7 +75,7 @@ BOOST_AUTO_TEST_CASE(CalArray_ROOTIO) f->WriteObject(&roc, "roc"); delete f; - //CalROC *rocRead = nullptr; + // CalROC *rocRead = nullptr; CalArray* rocRead = nullptr; f = TFile::Open("CalArray_ROOTIO.root"); f->GetObject("roc", rocRead); @@ -201,7 +225,7 @@ BOOST_AUTO_TEST_CASE(CalDet_Arithmetics) // // ===| test operators with simple numbers |================================== // - const float number = 0.2; + const float number = 0.2f; bool isEqual = true; // + operator @@ -320,4 +344,4 @@ BOOST_AUTO_TEST_CASE(CalDetTypeTest) BOOST_CHECK(testDict == true); } -} // namespace o2 +} // namespace o2::tpc