1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 /* Various predicates and operations on IEEE-754 floating point types. */
9 #ifndef mozilla_FloatingPoint_h
10 #define mozilla_FloatingPoint_h
12 #include "mozilla/Assertions.h"
13 #include "mozilla/Attributes.h"
14 #include "mozilla/Casting.h"
15 #include "mozilla/MathAlgorithms.h"
16 #include "mozilla/Types.h"
23 * It's reasonable to ask why we have this header at all. Don't isnan,
24 * copysign, the built-in comparison operators, and the like solve these
25 * problems? Unfortunately, they don't. We've found that various compilers
26 * (MSVC, MSVC when compiling with PGO, and GCC on OS X, at least) miscompile
27 * the standard methods in various situations, so we can't use them. Some of
28 * these compilers even have problems compiling seemingly reasonable bitwise
29 * algorithms! But with some care we've found algorithms that seem to not
30 * trigger those compiler bugs.
32 * For the aforementioned reasons, be very wary of making changes to any of
33 * these algorithms. If you must make changes, keep a careful eye out for
34 * compiler bustage, particularly PGO-specific bustage.
37 struct FloatTypeTraits
39 typedef uint32_t Bits
;
41 static const unsigned ExponentBias
= 127;
42 static const unsigned ExponentShift
= 23;
44 static const Bits SignBit
= 0x80000000UL
;
45 static const Bits ExponentBits
= 0x7F800000UL
;
46 static const Bits SignificandBits
= 0x007FFFFFUL
;
49 struct DoubleTypeTraits
51 typedef uint64_t Bits
;
53 static const unsigned ExponentBias
= 1023;
54 static const unsigned ExponentShift
= 52;
56 static const Bits SignBit
= 0x8000000000000000ULL
;
57 static const Bits ExponentBits
= 0x7ff0000000000000ULL
;
58 static const Bits SignificandBits
= 0x000fffffffffffffULL
;
61 template<typename T
> struct SelectTrait
;
62 template<> struct SelectTrait
<float> : public FloatTypeTraits
{};
63 template<> struct SelectTrait
<double> : public DoubleTypeTraits
{};
66 * This struct contains details regarding the encoding of floating-point
67 * numbers that can be useful for direct bit manipulation. As of now, the
68 * template parameter has to be float or double.
70 * The nested typedef |Bits| is the unsigned integral type with the same size
71 * as T: uint32_t for float and uint64_t for double (static assertions
72 * double-check these assumptions).
74 * ExponentBias is the offset that is subtracted from the exponent when
75 * computing the value, i.e. one plus the opposite of the mininum possible
77 * ExponentShift is the shift that one needs to apply to retrieve the exponent
78 * component of the value.
80 * SignBit contains a bits mask. Bit-and-ing with this mask will result in
81 * obtaining the sign bit.
82 * ExponentBits contains the mask needed for obtaining the exponent bits and
83 * SignificandBits contains the mask needed for obtaining the significand bits.
85 * Full details of how floating point number formats are encoded are beyond the
86 * scope of this comment. For more information, see
87 * http://en.wikipedia.org/wiki/IEEE_floating_point
88 * http://en.wikipedia.org/wiki/Floating_point#IEEE_754:_floating_point_in_modern_computers
91 struct FloatingPoint
: public SelectTrait
<T
>
93 typedef SelectTrait
<T
> Base
;
94 typedef typename
Base::Bits Bits
;
96 static_assert((Base::SignBit
& Base::ExponentBits
) == 0,
97 "sign bit shouldn't overlap exponent bits");
98 static_assert((Base::SignBit
& Base::SignificandBits
) == 0,
99 "sign bit shouldn't overlap significand bits");
100 static_assert((Base::ExponentBits
& Base::SignificandBits
) == 0,
101 "exponent bits shouldn't overlap significand bits");
103 static_assert((Base::SignBit
| Base::ExponentBits
| Base::SignificandBits
) ==
105 "all bits accounted for");
108 * These implementations assume float/double are 32/64-bit single/double format
109 * number types compatible with the IEEE-754 standard. C++ don't require this
110 * to be the case. But we required this in implementations of these algorithms
111 * that preceded this header, so we shouldn't break anything if we keep doing so.
113 static_assert(sizeof(T
) == sizeof(Bits
), "Bits must be same size as T");
116 /** Determines whether a double is NaN. */
118 static MOZ_ALWAYS_INLINE
bool
122 * A float/double is NaN if all exponent bits are 1 and the significand contains at
123 * least one non-zero bit.
125 typedef FloatingPoint
<T
> Traits
;
126 typedef typename
Traits::Bits Bits
;
127 Bits bits
= BitwiseCast
<Bits
>(t
);
128 return (bits
& Traits::ExponentBits
) == Traits::ExponentBits
&&
129 (bits
& Traits::SignificandBits
) != 0;
132 /** Determines whether a float/double is +Infinity or -Infinity. */
134 static MOZ_ALWAYS_INLINE
bool
137 /* Infinities have all exponent bits set to 1 and an all-0 significand. */
138 typedef FloatingPoint
<T
> Traits
;
139 typedef typename
Traits::Bits Bits
;
140 Bits bits
= BitwiseCast
<Bits
>(t
);
141 return (bits
& ~Traits::SignBit
) == Traits::ExponentBits
;
144 /** Determines whether a float/double is not NaN or infinite. */
146 static MOZ_ALWAYS_INLINE
bool
150 * NaN and Infinities are the only non-finite floats/doubles, and both have all
151 * exponent bits set to 1.
153 typedef FloatingPoint
<T
> Traits
;
154 typedef typename
Traits::Bits Bits
;
155 Bits bits
= BitwiseCast
<Bits
>(t
);
156 return (bits
& Traits::ExponentBits
) != Traits::ExponentBits
;
160 * Determines whether a float/double is negative. It is an error to call this method
161 * on a float/double which is NaN.
164 static MOZ_ALWAYS_INLINE
bool
167 MOZ_ASSERT(!IsNaN(t
), "NaN does not have a sign");
169 /* The sign bit is set if the double is negative. */
170 typedef FloatingPoint
<T
> Traits
;
171 typedef typename
Traits::Bits Bits
;
172 Bits bits
= BitwiseCast
<Bits
>(t
);
173 return (bits
& Traits::SignBit
) != 0;
176 /** Determines whether a float/double represents -0. */
178 static MOZ_ALWAYS_INLINE
bool
181 /* Only the sign bit is set if the value is -0. */
182 typedef FloatingPoint
<T
> Traits
;
183 typedef typename
Traits::Bits Bits
;
184 Bits bits
= BitwiseCast
<Bits
>(t
);
185 return bits
== Traits::SignBit
;
189 * Returns the exponent portion of the float/double.
191 * Zero is not special-cased, so ExponentComponent(0.0) is
192 * -int_fast16_t(Traits::ExponentBias).
195 static MOZ_ALWAYS_INLINE
int_fast16_t
196 ExponentComponent(T t
)
199 * The exponent component of a float/double is an unsigned number, biased from its
200 * actual value. Subtract the bias to retrieve the actual exponent.
202 typedef FloatingPoint
<T
> Traits
;
203 typedef typename
Traits::Bits Bits
;
204 Bits bits
= BitwiseCast
<Bits
>(t
);
205 return int_fast16_t((bits
& Traits::ExponentBits
) >> Traits::ExponentShift
) -
206 int_fast16_t(Traits::ExponentBias
);
209 /** Returns +Infinity. */
211 static MOZ_ALWAYS_INLINE T
215 * Positive infinity has all exponent bits set, sign bit set to 0, and no
218 typedef FloatingPoint
<T
> Traits
;
219 return BitwiseCast
<T
>(Traits::ExponentBits
);
222 /** Returns -Infinity. */
224 static MOZ_ALWAYS_INLINE T
228 * Negative infinity has all exponent bits set, sign bit set to 1, and no
231 typedef FloatingPoint
<T
> Traits
;
232 return BitwiseCast
<T
>(Traits::SignBit
| Traits::ExponentBits
);
236 /** Constructs a NaN value with the specified sign bit and significand bits. */
238 static MOZ_ALWAYS_INLINE T
239 SpecificNaN(int signbit
, typename FloatingPoint
<T
>::Bits significand
)
241 typedef FloatingPoint
<T
> Traits
;
242 MOZ_ASSERT(signbit
== 0 || signbit
== 1);
243 MOZ_ASSERT((significand
& ~Traits::SignificandBits
) == 0);
244 MOZ_ASSERT(significand
& Traits::SignificandBits
);
246 T t
= BitwiseCast
<T
>((signbit
? Traits::SignBit
: 0) |
247 Traits::ExponentBits
|
249 MOZ_ASSERT(IsNaN(t
));
253 /** Computes the smallest non-zero positive float/double value. */
255 static MOZ_ALWAYS_INLINE T
258 typedef FloatingPoint
<T
> Traits
;
259 typedef typename
Traits::Bits Bits
;
260 return BitwiseCast
<T
>(Bits(1));
264 * If t is equal to some int32_t value, set *i to that value and return true;
265 * otherwise return false.
267 * Note that negative zero is "equal" to zero here. To test whether a value can
268 * be losslessly converted to int32_t and back, use NumberIsInt32 instead.
271 static MOZ_ALWAYS_INLINE
bool
272 NumberEqualsInt32(T t
, int32_t* i
)
275 * XXX Casting a floating-point value that doesn't truncate to int32_t, to
276 * int32_t, induces undefined behavior. We should definitely fix this
277 * (bug 744965), but as apparently it "works" in practice, it's not a
278 * pressing concern now.
280 return t
== (*i
= int32_t(t
));
284 * If d can be converted to int32_t and back to an identical double value,
285 * set *i to that value and return true; otherwise return false.
287 * The difference between this and NumberEqualsInt32 is that this method returns
288 * false for negative zero.
291 static MOZ_ALWAYS_INLINE
bool
292 NumberIsInt32(T t
, int32_t* i
)
294 return !IsNegativeZero(t
) && NumberEqualsInt32(t
, i
);
298 * Computes a NaN value. Do not use this method if you depend upon a particular
299 * NaN value being returned.
302 static MOZ_ALWAYS_INLINE T
306 * If we can use any quiet NaN, we might as well use the all-ones NaN,
307 * since it's cheap to materialize on common platforms (such as x64, where
308 * this value can be represented in a 32-bit signed immediate field, allowing
309 * it to be stored to memory in a single instruction).
311 typedef FloatingPoint
<T
> Traits
;
312 return SpecificNaN
<T
>(1, Traits::SignificandBits
);
316 * Compare two doubles for equality, *without* equating -0 to +0, and equating
317 * any NaN value to any other NaN value. (The normal equality operators equate
318 * -0 with +0, and they equate NaN to no other value.)
322 NumbersAreIdentical(T t1
, T t2
)
324 typedef FloatingPoint
<T
> Traits
;
325 typedef typename
Traits::Bits Bits
;
328 return BitwiseCast
<Bits
>(t1
) == BitwiseCast
<Bits
>(t2
);
334 struct FuzzyEqualsEpsilon
;
337 struct FuzzyEqualsEpsilon
<float>
339 // A number near 1e-5 that is exactly representable in
341 static float value() { return 1.0f
/ (1 << 17); }
345 struct FuzzyEqualsEpsilon
<double>
347 // A number near 1e-12 that is exactly representable in
349 static double value() { return 1.0 / (1LL << 40); }
352 } // namespace detail
355 * Compare two floating point values for equality, modulo rounding error. That
356 * is, the two values are considered equal if they are both not NaN and if they
357 * are less than or equal to epsilon apart. The default value of epsilon is near
360 * For most scenarios you will want to use FuzzyEqualsMultiplicative instead,
361 * as it is more reasonable over the entire range of floating point numbers.
362 * This additive version should only be used if you know the range of the numbers
363 * you are dealing with is bounded and stays around the same order of magnitude.
366 static MOZ_ALWAYS_INLINE
bool
367 FuzzyEqualsAdditive(T val1
, T val2
, T epsilon
= detail::FuzzyEqualsEpsilon
<T
>::value())
369 static_assert(IsFloatingPoint
<T
>::value
, "floating point type required");
370 return Abs(val1
- val2
) <= epsilon
;
374 * Compare two floating point values for equality, allowing for rounding error
375 * relative to the magnitude of the values. That is, the two values are
376 * considered equal if they are both not NaN and they are less than or equal to
377 * some epsilon apart, where the epsilon is scaled by the smaller of the two
380 * In most cases you will want to use this rather than FuzzyEqualsAdditive, as
381 * this function effectively masks out differences in the bottom few bits of
382 * the floating point numbers being compared, regardless of what order of magnitude
383 * those numbers are at.
386 static MOZ_ALWAYS_INLINE
bool
387 FuzzyEqualsMultiplicative(T val1
, T val2
, T epsilon
= detail::FuzzyEqualsEpsilon
<T
>::value())
389 static_assert(IsFloatingPoint
<T
>::value
, "floating point type required");
390 // can't use std::min because of bug 965340
391 T smaller
= Abs(val1
) < Abs(val2
) ? Abs(val1
) : Abs(val2
);
392 return Abs(val1
- val2
) <= epsilon
* smaller
;
396 * Returns true if the given value can be losslessly represented as an IEEE-754
397 * single format number, false otherwise. All NaN values are considered
398 * representable (notwithstanding that the exact bit pattern of a double format
399 * NaN value can't be exactly represented in single format).
401 * This function isn't inlined to avoid buggy optimizations by MSVC.
403 MOZ_WARN_UNUSED_RESULT
405 IsFloat32Representable(double x
);
407 } /* namespace mozilla */
409 #endif /* mozilla_FloatingPoint_h */