1#pragma once
2
3#include <cmath>
4// Copyright 2005, Google Inc.
5// All rights reserved.
6//
7// Redistribution and use in source and binary forms, with or without
8// modification, are permitted provided that the following conditions are
9// met:
10//
11// * Redistributions of source code must retain the above copyright
12// notice, this list of conditions and the following disclaimer.
13// * Redistributions in binary form must reproduce the above
14// copyright notice, this list of conditions and the following disclaimer
15// in the documentation and/or other materials provided with the
16// distribution.
17// * Neither the name of Google Inc. nor the names of its
18// contributors may be used to endorse or promote products derived from
19// this software without specific prior written permission.
20//
21// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32//
33// The Google C++ Testing and Mocking Framework (Google Test)
34//
35// This header file declares functions and macros used internally by
36// Google Test. They are subject to change without notice.
37
38using Bits = uint32_t;
39
40// this avoids the "dereferencing type-punned pointer
41// will break strict-aliasing rules" error
42union Float {
43 float float_;
44 Bits bits_;
45};
46
47// # of bits in a number.
48static const size_t kBitCount = 8 * sizeof(Bits);
49// The mask for the sign bit.
50static const Bits kSignBitMask = static_cast<Bits>(1) << (kBitCount - 1);
51
52// GOOGLETEST_CM0001 DO NOT DELETE
53
54// Converts an integer from the sign-and-magnitude representation to
55// the biased representation. More precisely, let N be 2 to the
56// power of (kBitCount - 1), an integer x is represented by the
57// unsigned number x + N.
58//
59// For instance,
60//
61// -N + 1 (the most negative number representable using
62// sign-and-magnitude) is represented by 1;
63// 0 is represented by N; and
64// N - 1 (the biggest number representable using
65// sign-and-magnitude) is represented by 2N - 1.
66//
67// Read http://en.wikipedia.org/wiki/Signed_number_representations
68// for more details on signed number representations.
69static Bits SignAndMagnitudeToBiased(const Bits& sam) {
70 if (kSignBitMask & sam) {
71 // sam represents a negative number.
72 return ~sam + 1;
73 } else {
74 // sam represents a positive number.
75 return kSignBitMask | sam;
76 }
77}
78
79// Given two numbers in the sign-and-magnitude representation,
80// returns the distance between them as an unsigned number.
81static Bits DistanceBetweenSignAndMagnitudeNumbers(
82 const Bits& sam1,
83 const Bits& sam2) {
84 const Bits biased1 = SignAndMagnitudeToBiased(sam1);
85 const Bits biased2 = SignAndMagnitudeToBiased(sam2);
86 return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1);
87}
88
89// How many ULP's (Units in the Last Place) we want to tolerate when
90// comparing two numbers. The larger the value, the more error we
91// allow. A 0 value means that two numbers must be exactly the same
92// to be considered equal.
93//
94// The maximum error of a single floating-point operation is 0.5
95// units in the last place. On Intel CPU's, all floating-point
96// calculations are done with 80-bit precision, while double has 64
97// bits. Therefore, 4 should be enough for ordinary use.
98//
99// See the following article for more details on ULP:
100// http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
101static const size_t kMaxUlps = 4;
102
103// Returns true if and only if this number is at most kMaxUlps ULP's away
104// from rhs. In particular, this function:
105//
106// - returns false if either number is (or both are) NAN.
107// - treats really large numbers as almost equal to infinity.
108// - thinks +0.0 and -0.0 are 0 DLP's apart.
109inline bool AlmostEquals(float lhs, float rhs) {
110 // The IEEE standard says that any comparison operation involving
111 // a NAN must return false.
112 if (std::isnan(lhs) || std::isnan(rhs))
113 return false;
114
115 Float l = {lhs};
116 Float r = {rhs};
117
118 return DistanceBetweenSignAndMagnitudeNumbers(l.bits_, r.bits_) <= kMaxUlps;
119}
120