Motive Animation System
An open source project by FPL.
 All Classes Functions Variables Typedefs Friends Pages
float.h
1 // Copyright 2016 Google Inc. All rights reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef MOTIVE_MATH_FLOAT_H_
16 #define MOTIVE_MATH_FLOAT_H_
17 
18 #include <algorithm>
19 #include <cmath>
20 
21 #include "motive/math/range.h"
22 
23 namespace motive {
24 
25 // Internal constants to extract the exponent from a float.
26 // See: https://en.wikipedia.org/wiki/Single-precision_floating-point_format
27 static const uint32_t kExponentMask = 0x000000FF;
28 static const int kExponentShift = 23;
29 static const int kExponentOffset = 127;
30 
31 // Floats are represented as (sign) * 2^i * (1 + mantissa/2^23).
32 // These exponent constants represent special values for the i.
33 // Note that infinity and zero have special representations, but
34 // ones that make sense (infinity is the biggest positive exponent,
35 // and zero is the biggest negative exponent).
36 static const int kInfinityExponent = 128;
37 static const int kMaxFloatExponent = 127;
38 static const int kMaxInvertableExponent = 126;
39 static const int kMinInvertableExponent = -126;
40 static const int kMinFloatExponent = -126;
41 static const int kZeroExponent = -127;
42 
43 // Floating point representations of the exponent consts above.
44 extern const float kMinInvertablePowerOf2; // 2^kMinInvertableExponent
45 extern const float kMaxInvertablePowerOf2; // 2^kMaxInvertableExponent
46 extern const Range kInvertablePowerOf2Range; // (min, max) of above.
47 
48 // Used internally to bit-wise process floating point values.
50  uint32_t i;
51  float f;
52 };
53 
54 /// @brief Return floor(log2(fabs(f))), as an int.
55 /// When f is 0, return kZeroExponent.
56 /// When f is denormalized (i.e. has abs < min float), return kZeroExponent.
57 /// When f is between min and max float, return i where f = 2^i * mantissa.
58 /// When f is infinity, return kInfinityExponent.
59 /// When f is NaN (not a number), return kInfinityExponent.
60 inline int ExponentAsInt(const float f) {
61  IntFloatUnion u;
62  u.f = f;
63  return ((u.i >> kExponentShift) & kExponentMask) - kExponentOffset;
64 }
65 
66 /// @brief Return 2^i, as a float.
67 /// When i is kZeroExponent, return 0.
68 /// When i is kInfinityExponent, return +infinity.
69 /// When i is between kMinInvertableExponent and kMaxInvertableExponent,
70 /// return 2^i.
71 inline float ExponentFromInt(const int i) {
72  IntFloatUnion u;
73  u.i = ((i + kExponentOffset) & kExponentMask) << kExponentShift;
74  return u.f;
75 }
76 
77 /// @brief Returns the reciprocal of the exponent component of f.
78 /// Note that this will always be a power of 2.
79 /// e.g. f = 2.0, 2.1, or 3.99999 --> returns 0.5
80 /// e.g. f = 1/4 = 0.25 --> returns 4
81 /// Useful to bring a number near 1 (i.e. between 0.5f and 2.0f), without losing
82 /// any precision. Note that the mantissa does not change when multiplying by a
83 /// power of 2.
84 /// f must have exponent be between kMinInvertablePowerOf2 and
85 /// kMaxInvertablePowerOf2.
86 inline float ReciprocalExponent(const float f) {
87  return ExponentFromInt(-ExponentAsInt(f));
88 }
89 
90 /// @brief Returns the square root of the reciprocal of the exponent component
91 /// of f, rounded down to the nearest power of 2.
92 /// e.g. f = 4.0 --> returns 0.5
93 /// e.g. f = 8.0 --> also returns 0.5, since sqrt(1/8) rounded down to power of
94 /// 2 is 1/2.
95 /// e.g. f = 0.126 ~ 0.25 --> returns 2
96 inline float SqrtReciprocalExponent(const float f) {
97  return ExponentFromInt(-ExponentAsInt(f) / 2);
98 }
99 
100 /// @brief Returns the maximum power of 2 by which f can be multiplied and still
101 /// have exponent less than 2^max_exponent.
102 inline float MaxPowerOf2Scale(const float f, const int max_exponent) {
103  return ExponentFromInt(
104  std::min(kMaxFloatExponent, max_exponent - ExponentAsInt(f)));
105 }
106 
107 /// @brief If the absolute value of `x` is less than epsilon, return zero.
108 /// Otherwise, return `x`.
109 /// This function is useful in situations where the mathematical result depends
110 /// on knowing if a number is zero or not.
111 inline float ClampNearZero(const float x, const float epsilon) {
112  const bool is_near_zero = std::fabs(x) <= epsilon;
113  return is_near_zero ? 0.0f : x;
114 }
115 
116 } // namespace motive
117 
118 #endif // MOTIVE_MATH_FLOAT_H_
Definition: float.h:49