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