VirtualFluids 0.2.0
Parallel CFD LBM Solver
Loading...
Searching...
No Matches
AlmostEquals.h
Go to the documentation of this file.
1//=======================================================================================
2// ____ ____ __ ______ __________ __ __ __ __
3// \ \ | | | | | _ \ |___ ___| | | | | / \ | |
4// \ \ | | | | | |_) | | | | | | | / \ | |
5// \ \ | | | | | _ / | | | | | | / /\ \ | |
6// \ \ | | | | | | \ \ | | | \__/ | / ____ \ | |____
7// \ \ | | |__| |__| \__\ |__| \________/ /__/ \__\ |_______|
8// \ \ | | ________________________________________________________________
9// \ \ | | | ______________________________________________________________|
10// \ \| | | | __ __ __ __ ______ _______
11// \ | | |_____ | | | | | | | | | _ \ / _____)
12// \ | | _____| | | | | | | | | | | \ \ \_______
13// \ | | | | |_____ | \_/ | | | | |_/ / _____ |
14// \ _____| |__| |________| \_______/ |__| |______/ (_______/
15//
16// This file is part of VirtualFluids. VirtualFluids is free software: you can
17// redistribute it and/or modify it under the terms of the GNU General Public
18// License as published by the Free Software Foundation, either version 3 of
19// the License, or (at your option) any later version.
20//
21// VirtualFluids is distributed in the hope that it will be useful, but WITHOUT
22// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
23// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24// for more details.
25//
26// SPDX-License-Identifier: GPL-3.0-or-later
27// SPDX-FileCopyrightText: Copyright © VirtualFluids Project contributors, see AUTHORS.md in root folder
28//
32//=======================================================================================
33// Copyright 2005, Google Inc.
34// All rights reserved.
35//
36// Redistribution and use in source and binary forms, with or without
37// modification, are permitted provided that the following conditions are
38// met:
39//
40// * Redistributions of source code must retain the above copyright
41// notice, this list of conditions and the following disclaimer.
42// * Redistributions in binary form must reproduce the above
43// copyright notice, this list of conditions and the following disclaimer
44// in the documentation and/or other materials provided with the
45// distribution.
46// * Neither the name of Google Inc. nor the names of its
47// contributors may be used to endorse or promote products derived from
48// this software without specific prior written permission.
49//
50// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61//
62// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee)
63//
64// The Google C++ Testing Framework (Google Test)
65//
66// This header file declares functions and macros used internally by
67// Google Test. They are subject to change without notice.
68
69#pragma once
70
71#include <limits>
72#include <float.h>
73
74// This template class serves as a compile-time function from size to
75// type. It maps a size in bytes to a primitive type with that
76// size. e.g.
77//
78// TypeWithSize<4>::UInt
79//
80// is typedef-ed to be unsigned int (unsigned integer made up of 4
81// bytes).
82//
83// Such functionality should belong to STL, but I cannot find it
84// there.
85//
86// Google Test uses this class in the implementation of floating-point
87// comparison.
88//
89// For now it only handles UInt (unsigned int) as that's all Google Test
90// needs. Other types can be easily added in the future if need
91// arises.
92template <size_t size>
93class TypeWithSize {
94public:
95 // This prevents the user from using TypeWithSize<N> with incorrect
96 // values of N.
97 typedef void UInt;
98};
99
100// The specialization for size 4.
101template <>
102class TypeWithSize<4> {
103public:
104 // unsigned int has size 4 in both gcc and MSVC.
105 //
106 // As base/basictypes.h doesn't compile on Windows, we cannot use
107 // uint32, uint64, and etc here.
108 typedef int Int;
109 typedef unsigned int UInt;
110};
111
112// The specialization for size 8.
113template <>
114class TypeWithSize<8> {
115public:
116#if _MSC_VER
117 typedef __int64 Int;
118 typedef unsigned __int64 UInt;
119#else
120 typedef long long Int; // NOLINT
121 typedef unsigned long long UInt; // NOLINT
122#endif // _MSC_VER
123};
124
125// This template class represents an IEEE floating-point number
126// (either single-precision or double-precision, depending on the
127// template parameters).
128//
129// The purpose of this class is to do more sophisticated number
130// comparison. (Due to round-off error, etc, it's very unlikely that
131// two floating-points will be equal exactly. Hence a naive
132// comparison by the == operation often doesn't work.)
133//
134// Format of IEEE floating-point:
135//
136// The most-significant bit being the leftmost, an IEEE
137// floating-point looks like
138//
139// sign_bit exponent_bits fraction_bits
140//
141// Here, sign_bit is a single bit that designates the sign of the
142// number.
143//
144// For float, there are 8 exponent bits and 23 fraction bits.
145//
146// For double, there are 11 exponent bits and 52 fraction bits.
147//
148// More details can be found at
149// http://en.wikipedia.org/wiki/IEEE_floating-point_standard.
150//
151// Template parameter:
152//
153// RawType: the raw floating-point type (either float or double)
154template <typename RawType>
155class FloatingPoint {
156public:
157 // Defines the unsigned integer type that has the same size as the
158 // floating point number.
159 typedef typename TypeWithSize<sizeof(RawType)>::UInt Bits;
160
161 // Constants.
162
163 // # of bits in a number.
164 static const size_t kBitCount = 8 * sizeof(RawType);
165
166 // # of fraction bits in a number.
167 static const size_t kFractionBitCount =
168 std::numeric_limits<RawType>::digits - 1;
169
170 // # of exponent bits in a number.
171 static const size_t kExponentBitCount = kBitCount - 1 - kFractionBitCount;
172
173 // The mask for the sign bit.
174 static const Bits kSignBitMask = static_cast<Bits>(1) << (kBitCount - 1);
175
176 // The mask for the fraction bits.
177 static const Bits kFractionBitMask =
179
180 // The mask for the exponent bits.
182
183 // How many ULP's (Units in the Last Place) we want to tolerate when
184 // comparing two numbers. The larger the value, the more error we
185 // allow. A 0 value means that two numbers must be exactly the same
186 // to be considered equal.
187 //
188 // The maximum error of a single floating-point operation is 0.5
189 // units in the last place. On Intel CPU's, all floating-point
190 // calculations are done with 80-bit precision, while double has 64
191 // bits. Therefore, 4 should be enough for ordinary use.
192 //
193 // See the following article for more details on ULP:
194 // http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
195 static const size_t kMaxUlps = 4;
196
197 // Constructs a FloatingPoint from a raw floating-point number.
198 //
199 // On an Intel CPU, passing a non-normalized NAN (Not a Number)
200 // around may change its bits, although the new value is guaranteed
201 // to be also a NAN. Therefore, don't expect this constructor to
202 // preserve the bits in x when x is a NAN.
203 explicit FloatingPoint(const RawType& x) { u_.value_ = x; }
204
205 // Static methods
206
207 // Reinterprets a bit pattern as a floating-point number.
208 //
209 // This function is needed to test the AlmostEquals() method.
211 FloatingPoint fp(0);
212 fp.u_.bits_ = bits;
213 return fp.u_.value_;
214 }
215
216 // Returns the floating-point number that represent positive infinity.
217 static RawType Infinity() {
219 }
220
221 // Returns the maximum representable finite floating-point number.
222 static RawType Max();
223
224 // Non-static methods
225
226 // Returns the bits that represents this number.
227 const Bits &bits() const { return u_.bits_; }
228
229 // Returns the exponent bits of this number.
230 Bits exponent_bits() const { return kExponentBitMask & u_.bits_; }
231
232 // Returns the fraction bits of this number.
233 Bits fraction_bits() const { return kFractionBitMask & u_.bits_; }
234
235 // Returns the sign bit of this number.
236 Bits sign_bit() const { return kSignBitMask & u_.bits_; }
237
238 // Returns true iff this is NAN (not a number).
239 bool is_nan() const {
240 // It's a NAN if the exponent bits are all ones and the fraction
241 // bits are not entirely zeros.
242 return (exponent_bits() == kExponentBitMask) && (fraction_bits() != 0);
243 }
244
245 // Returns true iff this number is at most kMaxUlps ULP's away from
246 // rhs. In particular, this function:
247 //
248 // - returns false if either number is (or both are) NAN.
249 // - treats really large numbers as almost equal to infinity.
250 // - thinks +0.0 and -0.0 are 0 DLP's apart.
251 bool AlmostEquals(const FloatingPoint& rhs) const {
252 // The IEEE standard says that any comparison operation involving
253 // a NAN must return false.
254 if (is_nan() || rhs.is_nan()) return false;
255
256 return DistanceBetweenSignAndMagnitudeNumbers(u_.bits_, rhs.u_.bits_)
257 <= kMaxUlps;
258 }
259
260private:
261 // The data type used to store the actual floating-point number.
262 union FloatingPointUnion {
263 RawType value_; // The raw floating-point number.
264 Bits bits_; // The bits that represent the number.
265 };
266
267 // Converts an integer from the sign-and-magnitude representation to
268 // the biased representation. More precisely, let N be 2 to the
269 // power of (kBitCount - 1), an integer x is represented by the
270 // unsigned number x + N.
271 //
272 // For instance,
273 //
274 // -N + 1 (the most negative number representable using
275 // sign-and-magnitude) is represented by 1;
276 // 0 is represented by N; and
277 // N - 1 (the biggest number representable using
278 // sign-and-magnitude) is represented by 2N - 1.
279 //
280 // Read http://en.wikipedia.org/wiki/Signed_number_representations
281 // for more details on signed number representations.
282 static Bits SignAndMagnitudeToBiased(const Bits &sam) {
283 if (kSignBitMask & sam) {
284 // sam represents a negative number.
285 return ~sam + 1;
286 }
287 else {
288 // sam represents a positive number.
289 return kSignBitMask | sam;
290 }
291 }
292
293 // Given two numbers in the sign-and-magnitude representation,
294 // returns the distance between them as an unsigned number.
295 static Bits DistanceBetweenSignAndMagnitudeNumbers(const Bits &sam1,
296 const Bits &sam2) {
297 const Bits biased1 = SignAndMagnitudeToBiased(sam1);
298 const Bits biased2 = SignAndMagnitudeToBiased(sam2);
299 return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1);
300 }
301
302 FloatingPointUnion u_;
303};
304
305// We cannot use std::numeric_limits<T>::max() as it clashes with the max()
306// macro defined by <windows.h>.
307template <>
308inline float FloatingPoint<float>::Max() { return FLT_MAX; }
309template <>
310inline double FloatingPoint<double>::Max() { return DBL_MAX; }
311
312template <typename T>
static const size_t kMaxUlps
FloatingPoint(const RawType &x)
bool AlmostEquals(const FloatingPoint &rhs) const
static RawType Max()
Bits fraction_bits() const
static const size_t kExponentBitCount
static RawType ReinterpretBits(const Bits bits)
static const Bits kExponentBitMask
static const size_t kBitCount
TypeWithSize< sizeof(RawType)>::UInt Bits
static RawType Infinity()
Bits exponent_bits() const
static const Bits kFractionBitMask
bool is_nan() const
static const size_t kFractionBitCount
const Bits & bits() const
static const Bits kSignBitMask
Bits sign_bit() const
unsigned int UInt
unsigned long long UInt
bool AlmostEquals(T first, T second)
std::shared_ptr< T > SPtr
@ x
Definition Axis.h:42