Elements 6.1.2
A C++ base framework for the Euclid Software.
Loading...
Searching...
No Matches
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 <cmath> // for pow
25#include <cstdint> // for std::int64_t, std::int32_t
26#include <cstdlib> // for abs
27#include <limits> // for numeric_limits
28
29using std::abs;
31using std::pow;
32
33namespace Elements {
34
37
38// Usable AlmostEqual function
39bool almostEqual2sComplement(const float& left, const float& right, const int& max_ulps) {
40
41 using std::int32_t;
42 using std::uint32_t;
43
44 // int a_int = *(int*)&a;
45 int32_t a_int;
46 std::memcpy(&a_int, &left, sizeof(int32_t));
47 // Make a_int lexicographically ordered as a twos-complement int
48 if (a_int < 0) {
49 a_int = static_cast<int32_t>(0x80000000 - static_cast<uint32_t>(a_int));
50 }
51 // Make b_int lexicographically ordered as a twos-complement int
52 // int b_int = *(int*)&b;
53 int32_t b_int;
54 std::memcpy(&b_int, &right, sizeof(int32_t));
55 if (b_int < 0) {
56 b_int = static_cast<int32_t>(0x80000000 - static_cast<uint32_t>(b_int));
57 }
58 int32_t int_diff = abs(a_int - b_int);
59 if (int_diff <= max_ulps && -max_ulps <= int_diff) {
60 return true;
61 }
62 return false;
63}
64
65bool almostEqual2sComplement(const double& left, const double& right, const int& max_ulps) {
66
67 using std::int64_t;
68 using std::uint64_t;
69
70 // long long a_int = *(long long*)&a;
71
72 int64_t a_int;
73 std::memcpy(&a_int, &left, sizeof(a_int));
74 // Make a_int lexicographically ordered as a twos-complement int
75 if (a_int < 0) {
76 a_int = static_cast<int64_t>(0x8000000000000000LL - static_cast<uint64_t>(a_int));
77 }
78 // Make b_int lexicographically ordered as a twos-complement int
79 // long long b_int = *(long long*)&b;
80 int64_t b_int;
81 std::memcpy(&b_int, &right, sizeof(b_int));
82 if (b_int < 0) {
83 b_int = static_cast<int64_t>(0x8000000000000000LL - static_cast<uint64_t>(b_int));
84 }
85 int64_t int_diff = abs(a_int - b_int);
86 if (int_diff <= max_ulps && -max_ulps <= int_diff) {
87 return true;
88 }
89 return false;
90}
91
92template bool realBitWiseEqual<float>(const float& left, const float& right);
93template bool realBitWiseEqual<double>(const double& left, const double& right);
94
95} // namespace Elements
Floating point comparison implementations.
T memcpy(T... args)
template bool realBitWiseEqual< float >(const float &left, const float &right)
bool almostEqual2sComplement(ELEMENTS_UNUSED const FloatType &a, ELEMENTS_UNUSED const FloatType &b, ELEMENTS_UNUSED const std::size_t &max_ulps=0)
Definition: Real.h:328
ELEMENTS_API const double FLT_DEFAULT_TEST_TOLERANCE
Single precision float default test tolerance.
Definition: Real.cpp:35
ELEMENTS_API const double DBL_DEFAULT_TEST_TOLERANCE
Double precision float default test tolerance.
Definition: Real.cpp:36
template bool realBitWiseEqual< double >(const double &left, const double &right)
T pow(T... args)