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.
92
template
<
size_t
size>
93
class
TypeWithSize
{
94
public
:
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.
101
template
<>
102
class
TypeWithSize
<4> {
103
public
:
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.
113
template
<>
114
class
TypeWithSize
<8> {
115
public
:
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)
154
template
<
typename
RawType>
155
class
FloatingPoint
{
156
public
:
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
=
178
~static_cast<Bits>
(0) >> (
kExponentBitCount
+ 1);
179
180
// The mask for the exponent bits.
181
static
const
Bits
kExponentBitMask
= ~(
kSignBitMask
|
kFractionBitMask
);
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.
210
static
RawType
ReinterpretBits
(
const
Bits
bits
) {
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
() {
218
return
ReinterpretBits
(
kExponentBitMask
);
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
260
private
:
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>.
307
template
<>
308
inline
float
FloatingPoint<float>::Max
() {
return
FLT_MAX
; }
309
template
<>
310
inline
double
FloatingPoint<double>::Max
() {
return
DBL_MAX
; }
311
312
template
<
typename
T>
313
bool
AlmostEquals
(
T
first
,
T
second
)
314
{
315
FloatingPoint<T>
firstAsFloatingPoint
(
first
);
316
FloatingPoint<T>
secondAsFloatingPoint
(
second
);
317
318
return
firstAsFloatingPoint
.AlmostEquals(
secondAsFloatingPoint
);
319
}
FloatingPoint
Definition
AlmostEquals.h:155
FloatingPoint::kMaxUlps
static const size_t kMaxUlps
Definition
AlmostEquals.h:195
FloatingPoint::FloatingPoint
FloatingPoint(const RawType &x)
Definition
AlmostEquals.h:203
FloatingPoint::AlmostEquals
bool AlmostEquals(const FloatingPoint &rhs) const
Definition
AlmostEquals.h:251
FloatingPoint::Max
static RawType Max()
FloatingPoint::fraction_bits
Bits fraction_bits() const
Definition
AlmostEquals.h:233
FloatingPoint::kExponentBitCount
static const size_t kExponentBitCount
Definition
AlmostEquals.h:171
FloatingPoint::ReinterpretBits
static RawType ReinterpretBits(const Bits bits)
Definition
AlmostEquals.h:210
FloatingPoint::kExponentBitMask
static const Bits kExponentBitMask
Definition
AlmostEquals.h:181
FloatingPoint::kBitCount
static const size_t kBitCount
Definition
AlmostEquals.h:164
FloatingPoint::Bits
TypeWithSize< sizeof(RawType)>::UInt Bits
Definition
AlmostEquals.h:159
FloatingPoint::Infinity
static RawType Infinity()
Definition
AlmostEquals.h:217
FloatingPoint::exponent_bits
Bits exponent_bits() const
Definition
AlmostEquals.h:230
FloatingPoint::kFractionBitMask
static const Bits kFractionBitMask
Definition
AlmostEquals.h:177
FloatingPoint::is_nan
bool is_nan() const
Definition
AlmostEquals.h:239
FloatingPoint::kFractionBitCount
static const size_t kFractionBitCount
Definition
AlmostEquals.h:167
FloatingPoint::bits
const Bits & bits() const
Definition
AlmostEquals.h:227
FloatingPoint::kSignBitMask
static const Bits kSignBitMask
Definition
AlmostEquals.h:174
FloatingPoint::sign_bit
Bits sign_bit() const
Definition
AlmostEquals.h:236
TypeWithSize< 4 >::UInt
unsigned int UInt
Definition
AlmostEquals.h:109
TypeWithSize< 4 >::Int
int Int
Definition
AlmostEquals.h:108
TypeWithSize< 8 >::UInt
unsigned long long UInt
Definition
AlmostEquals.h:121
TypeWithSize< 8 >::Int
long long Int
Definition
AlmostEquals.h:120
TypeWithSize
Definition
AlmostEquals.h:93
TypeWithSize::UInt
void UInt
Definition
AlmostEquals.h:97
AlmostEquals
bool AlmostEquals(T first, T second)
Definition
AlmostEquals.h:313
SPtr
std::shared_ptr< T > SPtr
Definition
PointerDefinitions.h:39
x
@ x
Definition
Axis.h:42
tests
numerical-tests
gpu
NumericalTests
Utilities
Calculator
AlmostEquals.h
Generated on Fri May 15 2026 00:03:21 for VirtualFluids by
1.9.8