Elements  5.8
A C++ base framework for the Euclid Software.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
Real.cpp
Go to the documentation of this file.
1 /*
2  * @file Real.cpp
3  *
4  * @date Jun 13, 2013
5  * @author Hubert Degaudenzi
6  *
7  *
8  * @copyright 2012-2020 Euclid Science Ground Segment
9  *
10  * This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General
11  * Public License as published by the Free Software Foundation; either version 3.0 of the License, or (at your option)
12  * any later version.
13  *
14  * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
15  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include "ElementsKernel/Real.h"
23 
24 #include <cstdlib> // for abs
25 #include <limits> // for numeric_limits
26 #include <cstdint> // for std::int64_t, std::int32_t
27 #include <cmath> // for pow
28 
29 using std::abs;
30 using std::pow;
32 
33 namespace Elements {
34 
37 
38 // Usable AlmostEqual function
39 bool almostEqual2sComplement(const float& left, const float& right, const int& max_ulps) {
40 
41  using std::int32_t;
42 
43  // int a_int = *(int*)&a;
44  int32_t a_int = *reinterpret_cast<const int32_t *>(&left);
45  // Make a_int lexicographically ordered as a twos-complement int
46  if (a_int < 0) {
47  a_int = 0x80000000 - a_int;
48  }
49  // Make b_int lexicographically ordered as a twos-complement int
50  // int b_int = *(int*)&b;
51  int32_t b_int = *reinterpret_cast<const int32_t *>(&right);
52  if (b_int < 0) {
53  b_int = 0x80000000 - b_int;
54  }
55  int32_t int_diff = abs(a_int - b_int);
56  if (int_diff <= max_ulps && -max_ulps <= int_diff) {
57  return true;
58  }
59  return false;
60 }
61 
62 
63 bool almostEqual2sComplement(const double& left, const double& right, const int& max_ulps) {
64 
65  using std::int64_t;
66 
67  // long long a_int = *(long long*)&a;
68 
69  int64_t a_int = *reinterpret_cast<const int64_t *>(&left);
70  // Make a_int lexicographically ordered as a twos-complement int
71  if (a_int < 0) {
72  a_int = 0x8000000000000000LL - a_int;
73  }
74  // Make b_int lexicographically ordered as a twos-complement int
75  // long long b_int = *(long long*)&b;
76  int64_t b_int = *reinterpret_cast<const int64_t *>(&right);
77  if (b_int < 0) {
78  b_int = 0x8000000000000000LL - b_int;
79  }
80  int64_t int_diff = abs(a_int - b_int);
81  if (int_diff <= max_ulps && -max_ulps <= int_diff) {
82  return true;
83  }
84  return false;
85 }
86 
87 
88 template bool realBitWiseEqual<float>(const float& left, const float& right);
89 template bool realBitWiseEqual<double>(const double& left, const double& right);
90 
91 
92 } // namespace Elements
ELEMENTS_API const double DBL_DEFAULT_TEST_TOLERANCE
Double precision float default test tolerance.
Definition: Real.cpp:36
bool almostEqual2sComplement(ELEMENTS_UNUSED const FloatType &a, ELEMENTS_UNUSED const FloatType &b, ELEMENTS_UNUSED const std::size_t &max_ulps=0)
Definition: Real.h:330
Floating point comparison implementations.
template bool realBitWiseEqual< double >(const double &left, const double &right)
template bool realBitWiseEqual< float >(const float &left, const float &right)
T pow(T...args)
ELEMENTS_API const double FLT_DEFAULT_TEST_TOLERANCE
Single precision float default test tolerance.
Definition: Real.cpp:35