Elements 6.3.1
A C++ base framework for the Euclid Software.
Loading...
Searching...
No Matches
Real.h
Go to the documentation of this file.
1
40// Copyright 2005, Google Inc.
41// All rights reserved.
42//
43// Redistribution and use in source and binary forms, with or without
44// modification, are permitted provided that the following conditions are
45// met:
46//
47// * Redistributions of source code must retain the above copyright
48// notice, this list of conditions and the following disclaimer.
49// * Redistributions in binary form must reproduce the above
50// copyright notice, this list of conditions and the following disclaimer
51// in the documentation and/or other materials provided with the
52// distribution.
53// * Neither the name of Google Inc. nor the names of its
54// contributors may be used to endorse or promote products derived from
55// this software without specific prior written permission.
56//
57// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
58// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
59// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
60// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
61// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
62// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
63// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
64// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
65// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
66// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
67// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
68//
69// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee)
70//
71// The Google C++ Testing Framework (Google Test)
72#ifndef ELEMENTSKERNEL_ELEMENTSKERNEL_REAL_H_
73#define ELEMENTSKERNEL_ELEMENTSKERNEL_REAL_H_
74
75#include <cstring> // for memcpy
76#include <limits> // for numeric_limits
77
78#include "ElementsKernel/Export.h" // ELEMENTS_API
79#include "ElementsKernel/Unused.h" // ELEMENTS_UNUSED
80
81namespace Elements {
82
87
88// For testing purposes only. Rather use the isEqual functions for real
89// life comparison
94
95template <std::size_t size>
97public:
98 // This prevents the user from using TypeWithSize<N> with incorrect
99 // values of N.
100 using UInt = void;
101};
102
103// The specialisation for size 4.
104template <>
106public:
107 // unsigned int has size 4 in both gcc and MSVC.
108 //
109 // As base/basictypes.h doesn't compile on Windows, we cannot use
110 // uint32, uint64, and etc here.
111 using Int = int;
112 using UInt = unsigned int;
113};
114
115// The specialisation for size 8.
116template <>
118public:
119 using Int = long long; // NOLINT
120 using UInt = unsigned long long; // NOLINT
121};
122
123template <typename RawType>
125
126template <>
128
129template <>
131
132// This template class represents an IEEE floating-point number
133// (either single-precision or double-precision, depending on the
134// template parameters).
135//
136// The purpose of this class is to do more sophisticated number
137// comparison. (Due to round-off error, etc, it's very unlikely that
138// two floating-points will be equal exactly. Hence a naive
139// comparison by the == operation often doesn't work.)
140//
141// Format of IEEE floating-point:
142//
143// The most-significant bit being the leftmost, an IEEE
144// floating-point looks like
145//
146// sign_bit exponent_bits fraction_bits
147//
148// Here, sign_bit is a single bit that designates the sign of the
149// number.
150//
151// For float, there are 8 exponent bits and 23 fraction bits.
152//
153// For double, there are 11 exponent bits and 52 fraction bits.
154//
155// More details can be found at
156// http://en.wikipedia.org/wiki/IEEE_floating-point_standard.
157//
158// Template parameter:
159//
160// RawType: the raw floating-point type (either float or double)
161template <typename RawType>
163public:
164 // Defines the unsigned integer type that has the same size as the
165 // floating point number.
166 using Bits = typename TypeWithSize<sizeof(RawType)>::UInt;
167
168 // Constants.
169
170 // # of bits in a number.
171 static const std::size_t s_bitcount = 8 * sizeof(RawType);
172
173 // # of fraction bits in a number.
174 static const std::size_t s_fraction_bitcount = std::numeric_limits<RawType>::digits - 1;
175
176 // # of exponent bits in a number.
177 static const std::size_t s_exponent_bitcount = s_bitcount - 1 - s_fraction_bitcount;
178
179 // The mask for the sign bit.
180 static const Bits s_sign_bitmask = static_cast<Bits>(1) << (s_bitcount - 1);
181
182 // The mask for the fraction bits.
183 static const Bits s_fraction_bitmask = ~static_cast<Bits>(0) >> (s_exponent_bitcount + 1);
184
185 // The mask for the exponent bits.
186 static const Bits s_exponent_bitmask = ~(s_sign_bitmask | s_fraction_bitmask);
187
188 // How many ULP's (Units in the Last Place) we want to tolerate when
189 // comparing two numbers. The larger the value, the more error we
190 // allow. A 0 value means that two numbers must be exactly the same
191 // to be considered equal.
192 //
193 // The maximum error of a single floating-point operation is 0.5
194 // units in the last place. On Intel CPU's, all floating-point
195 // calculations are done with 80-bit precision, while double has 64
196 // bits. Therefore, 4 should be enough for ordinary use.
197 //
198 // See the following article for more details on ULP:
199 // http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm.
200 static const std::size_t m_max_ulps = defaultMaxUlps<RawType>();
201
202 // Constructs a FloatingPoint from a raw floating-point number.
203 //
204 // On an Intel CPU, passing a non-normalised NAN (Not a Number)
205 // around may change its bits, although the new value is guaranteed
206 // to be also a NAN. Therefore, don't expect this constructor to
207 // preserve the bits in x when x is a NAN.
208 explicit FloatingPoint(const RawType& x);
209
210 // Static methods
211
212 // Reinterprets a bit pattern as a floating-point number.
213 //
214 // This function is needed to test the AlmostEquals() method.
215 static RawType ReinterpretBits(const Bits& bits);
216
217 // Returns the floating-point number that represent positive infinity.
218 static RawType Infinity();
219
220 // Non-static methods
221
222 // Returns the bits that represents this number.
223 const Bits& bits() const;
224
225 // Returns the exponent bits of this number.
227
228 // Returns the fraction bits of this number.
230
231 // Returns the sign bit of this number.
232 Bits signBit() const;
233
234 // Returns true iff this is NAN (not a number).
235 bool isNan() const;
236
237 // Returns true iff this number is at most kMaxUlps ULP's away from
238 // rhs. In particular, this function:
239 //
240 // - returns false if either number is (or both are) NAN.
241 // - treats really large numbers as almost equal to infinity.
242 // - thinks +0.0 and -0.0 are 0 DLP's apart.
243 bool AlmostEquals(const FloatingPoint& rhs) const;
244
245 // Converts an integer from the sign-and-magnitude representation to
246 // the biased representation. More precisely, let N be 2 to the
247 // power of (kBitCount - 1), an integer x is represented by the
248 // unsigned number x + N.
249 //
250 // For instance,
251 //
252 // -N + 1 (the most negative number representable using
253 // sign-and-magnitude) is represented by 1;
254 // 0 is represented by N; and
255 // N - 1 (the biggest number representable using
256 // sign-and-magnitude) is represented by 2N - 1.
257 //
258 // Read http://en.wikipedia.org/wiki/Signed_number_representations
259 // for more details on signed number representations.
261
262 // Given two numbers in the sign-and-magnitude representation,
263 // returns the distance between them as an unsigned number.
264 static Bits distanceBetweenSignAndMagnitudeNumbers(const Bits& sam1, const Bits& sam2);
265
266private:
267 // The data type used to store the actual floating-point number.
269 RawType m_value; // The raw floating-point number.
270 Bits m_bits; // The bits that represent the number.
271 };
272
274};
275
276// Usable AlmostEqual function
277
278template <typename FloatType>
279ELEMENTS_API bool almostEqual2sComplement(ELEMENTS_UNUSED const FloatType& a, ELEMENTS_UNUSED const FloatType& b,
280 ELEMENTS_UNUSED const std::size_t& max_ulps = 0);
281
282template <typename RawType>
283ELEMENTS_API bool isNan(const RawType& x);
284
285template <typename RawType, std::size_t max_ulps = defaultMaxUlps<RawType>()>
286ELEMENTS_API bool isEqual(const RawType& left, const RawType& right);
287
288template <std::size_t max_ulps>
289ELEMENTS_API bool isEqual(const float& left, const float& right);
290
291template <std::size_t max_ulps>
292ELEMENTS_API bool isEqual(const double& left, const double& right);
293
294template <typename RawType, std::size_t max_ulps = defaultMaxUlps<RawType>()>
295ELEMENTS_API bool isNotEqual(const RawType& left, const RawType& right);
296
297template <std::size_t max_ulps>
298ELEMENTS_API bool isNotEqual(const float& left, const float& right);
299
300template <std::size_t max_ulps>
301ELEMENTS_API bool isNotEqual(const double& left, const double& right);
302
303template <typename RawType, std::size_t max_ulps = defaultMaxUlps<RawType>()>
304ELEMENTS_API bool isLess(const RawType& left, const RawType& right);
305
306template <std::size_t max_ulps>
307ELEMENTS_API bool isLess(const float& left, const float& right);
308
309template <std::size_t max_ulps>
310ELEMENTS_API bool isLess(const double& left, const double& right);
311
312template <typename RawType, std::size_t max_ulps = defaultMaxUlps<RawType>()>
313ELEMENTS_API bool isGreater(const RawType& left, const RawType& right);
314
315template <std::size_t max_ulps>
316ELEMENTS_API bool isGreater(const float& left, const float& right);
317
318template <std::size_t max_ulps>
319ELEMENTS_API bool isGreater(const double& left, const double& right);
320
321template <typename RawType, std::size_t max_ulps = defaultMaxUlps<RawType>()>
322ELEMENTS_API bool isLessOrEqual(const RawType& left, const RawType& right);
323
324template <std::size_t max_ulps>
325ELEMENTS_API bool isLessOrEqual(const float& left, const float& right);
326
327template <std::size_t max_ulps>
328ELEMENTS_API bool isLessOrEqual(const double& left, const double& right);
329
330template <typename RawType, std::size_t max_ulps = defaultMaxUlps<RawType>()>
331ELEMENTS_API bool isGreaterOrEqual(const RawType& left, const RawType& right);
332
333template <std::size_t max_ulps>
334ELEMENTS_API bool isGreaterOrEqual(const float& left, const float& right);
335
336template <std::size_t max_ulps>
337ELEMENTS_API bool isGreaterOrEqual(const double& left, const double& right);
338
355ELEMENTS_API bool almostEqual2sComplement(const float& left, const float& right,
356 const int& max_ulps = FLT_DEFAULT_MAX_ULPS);
373ELEMENTS_API bool almostEqual2sComplement(const double& left, const double& right,
374 const int& max_ulps = DBL_DEFAULT_MAX_ULPS);
375
389template <typename RawType>
390ELEMENTS_API bool realBitWiseEqual(const RawType& left, const RawType& right);
391
392} // namespace Elements
393
394#define ELEMENTSKERNEL_ELEMENTSKERNEL_REAL_IMPL_
395#include "ElementsKernel/_impl/Real.tpp" // IWYU pragma: export
396#undef ELEMENTSKERNEL_ELEMENTSKERNEL_REAL_IMPL_
397
398#endif // ELEMENTSKERNEL_ELEMENTSKERNEL_REAL_H_
399
defines the macros to be used for explicit export of the symbols
implementation of the templates declared in ElementsKernel/Real.h
Macro to silence unused variables warnings from the compiler.
FloatingPointUnion m_u
Definition Real.h:273
Bits fractionBits() const
typename TypeWithSize< sizeof(RawType)>::UInt Bits
Definition Real.h:166
static RawType ReinterpretBits(const Bits &bits)
FloatingPoint(const RawType &x)
static Bits distanceBetweenSignAndMagnitudeNumbers(const Bits &sam1, const Bits &sam2)
static Bits signAndMagnitudeToBiased(const Bits &sam)
static RawType Infinity()
bool AlmostEquals(const FloatingPoint &rhs) const
Bits exponentBits() const
const Bits & bits() const
unsigned long long UInt
Definition Real.h:120
#define ELEMENTS_API
Dummy definitions for the backward compatibility mode.
Definition Export.h:74
#define ELEMENTS_UNUSED
Definition Unused.h:39
ELEMENTS_API const double FLT_DEFAULT_TEST_TOLERANCE
Single precision float default test tolerance.
Definition Real.cpp:35
ELEMENTS_API bool isLess(const RawType &left, const RawType &right)
ELEMENTS_API bool isNotEqual(const RawType &left, const RawType &right)
ELEMENTS_API bool isGreater(const RawType &left, const RawType &right)
constexpr std::size_t FLT_DEFAULT_MAX_ULPS
Single precision float default maximum unit in the last place.
Definition Real.h:84
ELEMENTS_API bool isNan(const RawType &x)
ELEMENTS_API bool isEqual(const RawType &left, const RawType &right)
ELEMENTS_API const double DBL_DEFAULT_TEST_TOLERANCE
Double precision float default test tolerance.
Definition Real.cpp:36
ELEMENTS_API bool isLessOrEqual(const RawType &left, const RawType &right)
constexpr std::size_t DBL_DEFAULT_MAX_ULPS
Double precision float default maximum unit in the last place.
Definition Real.h:86
ELEMENTS_API bool realBitWiseEqual(const RawType &left, const RawType &right)
This function compares 2 floating point numbers bitwise. These are the strict equivalent of the "=="....
ELEMENTS_API constexpr std::size_t defaultMaxUlps< double >()
ELEMENTS_API constexpr std::size_t defaultMaxUlps< float >()
ELEMENTS_API bool almostEqual2sComplement(ELEMENTS_UNUSED const FloatType &a, ELEMENTS_UNUSED const FloatType &b, ELEMENTS_UNUSED const std::size_t &max_ulps=0)
ELEMENTS_API bool isGreaterOrEqual(const RawType &left, const RawType &right)
ELEMENTS_API constexpr std::size_t defaultMaxUlps()