2828namespace o2 ::tpc
2929{
3030
31- // templated euqality check
32- // for integer one would need a specialisation to check for == instead of <
31+ // templated euqality check
32+ // for integer one would need a specialisation to check for == instead of <
3333template <typename T>
34+ bool isEqualAbs (T x, T y, int n = 1 )
35+ {
36+ // Since `epsilon()` is the gap size (ULP, unit in the last place)
37+ // of floating-point numbers in interval [1, 2), we can scale it to
38+ // the gap size in interval [2^e, 2^{e+1}), where `e` is the exponent
39+ // of `x` and `y`.
40+
41+ // If `x` and `y` have different gap sizes (which means they have
42+ // different exponents), we take the smaller one. Taking the bigger
43+ // one is also reasonable, I guess.
44+ const T m = std::min (std::fabs (x), std::fabs (y));
45+
46+ // Subnormal numbers have fixed exponent, which is `min_exponent - 1`.
47+ const int exp = m < std::numeric_limits<T>::min ()
48+ ? std::numeric_limits<T>::min_exponent - 1
49+ : std::ilogb (m);
50+
51+ // We consider `x` and `y` equal if the difference between them is
52+ // within `n` ULPs.
53+ return std::fabs (x - y) <= n * std::ldexp (std::numeric_limits<T>::epsilon (), exp);
54+ }
55+
56+ template <typename T>
57+ requires (std::integral<T>)
3458bool isEqualAbs (T val1, T val2)
3559{
36- return std::abs ( val1 - val2) < std::numeric_limits<T>:: epsilon () ;
60+ return val1 == val2;
3761}
3862
3963BOOST_AUTO_TEST_CASE (CalArray_ROOTIO)
4064{
41- // CalROC roc(PadSubset::ROC, 10);
65+ // CalROC roc(PadSubset::ROC, 10);
4266 CalArray<unsigned > roc (PadSubset::ROC, 10 );
4367
4468 int iter = 0 ;
45- // unsigned iter=0;
69+ // unsigned iter=0;
4670 for (auto & val : roc.getData ()) {
4771 val = iter++;
4872 }
@@ -51,7 +75,7 @@ BOOST_AUTO_TEST_CASE(CalArray_ROOTIO)
5175 f->WriteObject (&roc, " roc" );
5276 delete f;
5377
54- // CalROC *rocRead = nullptr;
78+ // CalROC *rocRead = nullptr;
5579 CalArray<unsigned >* rocRead = nullptr ;
5680 f = TFile::Open (" CalArray_ROOTIO.root" );
5781 f->GetObject (" roc" , rocRead);
@@ -201,7 +225,7 @@ BOOST_AUTO_TEST_CASE(CalDet_Arithmetics)
201225 //
202226 // ===| test operators with simple numbers |==================================
203227 //
204- const float number = 0.2 ;
228+ const float number = 0 .2f ;
205229 bool isEqual = true ;
206230
207231 // + operator
@@ -320,4 +344,4 @@ BOOST_AUTO_TEST_CASE(CalDetTypeTest)
320344 BOOST_CHECK (testDict == true );
321345}
322346
323- } // namespace o2
347+ } // namespace o2::tpc
0 commit comments