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