OpenTTD Source: src/core/math_func.hpp Source File

OpenTTD Source 13.2.1

math_func.hpp
Go to the documentation of this file.
1 /*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6 */
7
10 #ifndef MATH_FUNC_HPP
11 #define MATH_FUNC_HPP
12
20 template <typename T>
21 static inline T abs(const T a)
22 {
23 return (a < (T)0) ? -a : a;
24 }
25
34 template <typename T>
35 static inline T Align(const T x, uint n)
36 {
37 assert((n & (n - 1)) == 0 && n != 0);
38 n--;
39 return (T)((x + n) & ~((T)n));
40 }
41
52 template <typename T>
53 static inline T *AlignPtr(T *x, uint n)
54 {
55 static_assert(sizeof(size_t) == sizeof(void *));
56 return reinterpret_cast<T *>(Align((size_t)x, n));
57 }
58
76 template <typename T>
77 static inline T Clamp(const T a, const T min, const T max)
78 {
79 assert(min <= max);
80 if (a <= min) return min;
81 if (a >= max) return max;
82 return a;
83 }
84
99 template <typename T>
100 static inline T SoftClamp(const T a, const T min, const T max)
101 {
102 if (min > max) {
103 using U = std::make_unsigned_t<T>;
104 return min - (U(min) - max) / 2;
105 }
106 if (a <= min) return min;
107 if (a >= max) return max;
108 return a;
109 }
110
127 static inline int Clamp(const int a, const int min, const int max)
128 {
129 return Clamp<int>(a, min, max);
130 }
131
148 static inline uint ClampU(const uint a, const uint min, const uint max)
149 {
150 return Clamp<uint>(a, min, max);
151 }
152
167 static inline int32 ClampToI32(const int64 a)
168 {
169 return static_cast<int32>(Clamp<int64>(a, INT32_MIN, INT32_MAX));
170 }
171
179 static inline uint16 ClampToU16(const uint64 a)
180 {
181 /* MSVC thinks, in its infinite wisdom, that int min(int, int) is a better
182 * match for min(uint64, uint) than uint64 min(uint64, uint64). As such we
183 * need to cast the UINT16_MAX to prevent MSVC from displaying its
184 * infinite loads of warnings. */
185 return static_cast<uint16>(std::min(a, static_cast<uint64>(UINT16_MAX)));
186 }
187
195 template <typename T>
196 static inline T Delta(const T a, const T b)
197 {
198 return (a < b) ? b - a : a - b;
199 }
200
213 template <typename T>
214 static inline bool IsInsideBS(const T x, const size_t base, const size_t size)
215 {
216 return (size_t)(x - base) < size;
217 }
218
229 template <typename T>
230 static constexpr inline bool IsInsideMM(const T x, const size_t min, const size_t max) noexcept
231 {
232 return (size_t)(x - min) < (max - min);
233 }
234
240 template <typename T>
241 static inline void Swap(T &a, T &b)
242 {
243 T t = a;
244 a = b;
245 b = t;
246 }
247
253 static inline uint ToPercent8(uint i)
254 {
255 assert(i < 256);
256 return i * 101 >> 8;
257 }
258
264 static inline uint ToPercent16(uint i)
265 {
266 assert(i < 65536);
267 return i * 101 >> 16;
268 }
269
270 int LeastCommonMultiple(int a, int b);
271 int GreatestCommonDivisor(int a, int b);
272 int DivideApprox(int a, int b);
273
280 static inline uint CeilDiv(uint a, uint b)
281 {
282 return (a + b - 1) / b;
283 }
284
291 static inline uint Ceil(uint a, uint b)
292 {
293 return CeilDiv(a, b) * b;
294 }
295
302 static inline int RoundDivSU(int a, uint b)
303 {
304 if (a > 0) {
305 /* 0.5 is rounded to 1 */
306 return (a + static_cast<int>(b) / 2) / static_cast<int>(b);
307 } else {
308 /* -0.5 is rounded to 0 */
309 return (a - (static_cast<int>(b) - 1) / 2) / static_cast<int>(b);
310 }
311 }
312
319 static inline int DivAwayFromZero(int a, uint b)
320 {
321 const int _b = static_cast<int>(b);
322 if (a > 0) {
323 return (a + _b - 1) / _b;
324 } else {
325 /* Note: Behaviour of negative numerator division is truncation toward zero. */
326 return (a - _b + 1) / _b;
327 }
328 }
329
330 uint32 IntSqrt(uint32 num);
331
332 #endif /* MATH_FUNC_HPP */
IsInsideMM
static constexpr bool IsInsideMM(const T x, const size_t min, const size_t max) noexcept
Checks if a value is in an interval.
Definition: math_func.hpp:230
ClampToI32
static int32 ClampToI32(const int64 a)
Reduce a signed 64-bit int to a signed 32-bit one.
Definition: math_func.hpp:167
ToPercent8
static uint ToPercent8(uint i)
Converts a "fract" value 0..255 to "percent" value 0..100.
Definition: math_func.hpp:253
ClampU
static uint ClampU(const uint a, const uint min, const uint max)
Clamp an unsigned integer between an interval.
Definition: math_func.hpp:148
LeastCommonMultiple
int LeastCommonMultiple(int a, int b)
Compute least common multiple (lcm) of arguments a and b, the smallest integer value that is a multip...
Definition: math_func.cpp:24
Align
static T Align(const T x, uint n)
Return the smallest multiple of n equal or greater than x.
Definition: math_func.hpp:35
IsInsideBS
static bool IsInsideBS(const T x, const size_t base, const size_t size)
Checks if a value is between a window started at some base point.
Definition: math_func.hpp:214
DivAwayFromZero
static int DivAwayFromZero(int a, uint b)
Computes (a / b) rounded away from zero.
Definition: math_func.hpp:319
RoundDivSU
static int RoundDivSU(int a, uint b)
Computes round(a / b) for signed a and unsigned b.
Definition: math_func.hpp:302
Clamp
static T Clamp(const T a, const T min, const T max)
Clamp a value between an interval.
Definition: math_func.hpp:77
IntSqrt
uint32 IntSqrt(uint32 num)
Compute the integer square root.
Definition: math_func.cpp:77
abs
static T abs(const T a)
Returns the absolute value of (scalar) variable.
Definition: math_func.hpp:21
Ceil
static uint Ceil(uint a, uint b)
Computes ceil(a / b) * b for non-negative a and b.
Definition: math_func.hpp:291
ToPercent16
static uint ToPercent16(uint i)
Converts a "fract" value 0..65535 to "percent" value 0..100.
Definition: math_func.hpp:264
ClampToU16
static uint16 ClampToU16(const uint64 a)
Reduce an unsigned 64-bit int to an unsigned 16-bit one.
Definition: math_func.hpp:179
CeilDiv
static uint CeilDiv(uint a, uint b)
Computes ceil(a / b) for non-negative a and b.
Definition: math_func.hpp:280
GreatestCommonDivisor
int GreatestCommonDivisor(int a, int b)
Compute greatest common divisor (gcd) of a and b.
Definition: math_func.cpp:39
SoftClamp
static T SoftClamp(const T a, const T min, const T max)
Clamp a value between an interval.
Definition: math_func.hpp:100
Swap
static void Swap(T &a, T &b)
Type safe swap operation.
Definition: math_func.hpp:241
AlignPtr
static T * AlignPtr(T *x, uint n)
Return the smallest multiple of n equal or greater than x Applies to pointers only.
Definition: math_func.hpp:53
Delta
static T Delta(const T a, const T b)
Returns the (absolute) difference between two (scalar) variables.
Definition: math_func.hpp:196
DivideApprox
int DivideApprox(int a, int b)
Deterministic approximate division.
Definition: math_func.cpp:57