11
#include "Constants.h"
14
template< class T > inline T Max3( const T A, const T B, const T C )
16
return Max ( Max( A, B ), C );
19
template< class T > inline T Min3( const T A, const T B, const T C )
21
return Min ( Min( A, B ), C );
24
template< class T > inline T Square( const T A )
28
template< class T > inline T Clamp( const T X, const T Min, const T Max )
30
return X<Min ? Min : X<Max ? X : Max;
33
template< class T > inline T ClampUp( const T X, const T Min, const T Max )
35
return X<Min ? Min : X;
38
template< class T > inline T ClampDown( const T X, const T Max )
40
return X>Max ? Max : X;
43
template< class T > inline T Align( const T Ptr, int Alignment )
45
return (T)(((INL_POINTER)Ptr + Alignment - 1) & ~(Alignment-1));
48
//Bitwise rotation on the left.
49
template<typename T> inline const T Rol(const T& a,const unsigned int n=1) { return (a<<n)|(a>>((sizeof(T)<<3)-n)); }
50
//Bitwise rotation on the right.
51
template<typename T> inline const T Ror(const T& a,const unsigned int n=1) { return (a>>n)|(a<<((sizeof(T)<<3)-n)); }
53
// Exchange the values of variables a and b
54
template<typename T> inline void Swap(T& a,T& b) { const T t=a; a=b; b=t; }
55
template<typename T> inline void Swap(T& a1,T& b1,T& a2,T& b2) { Swap(a1,b1); Swap(a2,b2); }
56
template<typename T> inline void Swap(T& a1,T& b1,T& a2,T& b2,T& a3,T& b3) { Swap(a1,b1,a2,b2); Swap(a3,b3); }
57
template<typename T> inline void Swap(T& a1,T& b1,T& a2,T& b2,T& a3,T& b3,T& a4,T& b4) { Swap(a1,b1,a2,b2,a3,b3); Swap(a4,b4); }
58
template<typename T> inline void Swap(T& a1,T& b1,T& a2,T& b2,T& a3,T& b3,T& a4,T& b4,T& a5,T& b5)
60
Swap(a1,b1,a2,b2,a3,b3,a4,b4); Swap(a5,b5);
62
template<typename T> inline void Swap(T& a1,T& b1,T& a2,T& b2,T& a3,T& b3,T& a4,T& b4,T& a5,T& b5,T& a6,T& b6)
64
Swap(a1,b1,a2,b2,a3,b3,a4,b4,a5,b5); Swap(a6,b6);
67
//Return the absolute value of a.
68
template<typename T> inline const T Abs(const T& a) { return a>=0?a:-a; }
69
//Return the minimum between a and b.
70
template<typename T> inline const T& Min(const T& a,const T& b) { return a<=b?a:b; }
71
//Return the minimum between a, b and c.
72
template<typename T> inline const T& Min(const T& a,const T& b,const T& c) { return min(min(a,b),c); }
73
//Return the minimum between a, b, c and d.
74
template<typename T> inline const T& Min(const T& a,const T& b,const T& c,const T& d) { return min(min(min(a,b),c),d); }
75
//Return the maximum between a and b.
76
template<typename T> inline const T& Max(const T& a,const T& b) { return a>=b?a:b; }
77
//Return the maximum between a, b and c.
78
template<typename T> inline const T& Max(const T& a,const T& b,const T& c) { return max(max(a,b),c); }
79
//Return the maximum between a,b,c and d.
80
template<typename T> inline const T& Max(const T& a,const T& b,const T& c,const T& d) { return max(max(a,b,c),d); }
81
//Return the sign of x.
82
template<typename T> inline T Sign(const T& x) { return (x<0)?-1:(x==0?0:1); }
85
template<typename T> inline T Modulo(const T& x,const T& m) { return x-m*(T)std::floor((double)x/m); }
87
inline int ModuloInt(const int x,const int m) { return x>=0?x%m:(x%m?m+x%m:0); }
89
template<typename T> inline T MinMod(const T& a,const T& b) { return a*b<=0?0:(a>0?(a<b?a:b):(a<b?b:a)); }
91
//Return a random variable between [0,1] (uniform distribution).
92
inline double Random() { return (double)std::rand()/RAND_MAX; }
94
//Return a random variable between [-1,1] (uniform distribution).
95
inline double CRandom() { return 1-2*std::rand(); }
97
//Return a random variable using a gaussian distribution and a variance of 1.
98
inline double RandomGaussian() { return std::sqrt(-2*std::log((double)(1e-10 + (1-2e-10)*std::rand())))*std::cos((double)(2*3.14f/*Const::pi*/*std::rand())); }
100
inline unsigned int RandomUInt() { return std::rand(); }
102
inline unsigned int RandomUInt(unsigned int max_random) { return std::rand() % max_random; }
104
inline t_size DiffPointer(void* Ptr0, void* Ptr1) {if((t_size)Ptr0 >= (t_size)Ptr1) return (t_size)((t_size)Ptr0 - (t_size)Ptr1); return (t_size)((t_size)Ptr1 - (t_size)Ptr0);}
106
template<typename T> inline T SubstractPointer(void* Ptr, t_size Value) {return (T)(((t_size)Ptr) - Value);}
107
template<typename T> inline T AddPointer(void* Ptr, t_size Value) {return (T)(((t_size)Ptr) + Value);}
109
//! Round up to the nearest multiple of Alignment that is greater or equal to Value
111
@param Alignment Must be a power of 2
113
template<typename T> inline T RoundUp(T Value, int Alignment)
115
return (Value + (Alignment-1)) & ~(Alignment-1);
118
//! Round down to the nearest multiple of Alignment that is smaller or equal to Value
120
@param Alignment Must be a power of 2
122
template<typename T> inline T RoundDown(T Value, int Alignment)
124
return ((Value) & ~(Alignment-1));
127
//! Return true is Value is aligned on Alignment
129
@param Alignment Must be a power of 2
131
template<typename T> inline bool IsAligned(T Value, int Alignment)
133
return (((Value) & ~(Alignment-1)) == 0);
140
inline t_u16 ReverseByteOrdering(t_u16 value)
143
t_u8 * src = (t_u8 *) &value;
144
t_u8 * dest = (t_u8 *) &temp;
154
0x00112233 -> 0x33221100
156
inline t_u32 ReverseByteOrdering(t_u32 value)
159
t_u8 * src = (t_u8 *) &value;
160
t_u8 * dest = (t_u8 *) &temp;
172
0x0011223344556677 -> 0x7766554433221100
174
inline t_u64 ReverseByteOrdering(t_u64 value)
177
t_u8 * src = (t_u8 *) &value;
178
t_u8 * dest = (t_u8 *) &temp;
194
// Determining if an integer is a power of 2
195
// http://graphics.stanford.edu/~seander/bithacks.html
196
inline bool IsPowerOf2(unsigned int n)
198
// The algorithm does not 0 consider 0 a power of two. (this is right)
199
return !(n & (n - 1)) && n;
202
// Compute the next highest power of 2 of 32-bit v
203
// http://graphics.stanford.edu/~seander/bithacks.html
204
inline unsigned int NextPowerOfTwo(unsigned int x)
215
inline unsigned int GetLowerPowerOfTwoExponent(unsigned int x)
226
inline unsigned int PowerOfTwo(int i)
229
unsigned int power = 1;
238
// ClearLSBBit(0x01001100) = 0x01001000
239
inline unsigned int Hak32_ClearLSBBit(unsigned int N)
244
// http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetKernighan
245
// Hak32_CountNumBits(0x01001100) = 3
246
inline unsigned int Hak32_CountNumBits(unsigned int N)
248
unsigned int v = N; // count the number of bits set in v
249
unsigned int c; // c accumulates the total bits set in v
252
v &= v - 1; // clear the least significant bit set
257
// http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetKernighan : Compute parity in parallel
258
inline unsigned int Hak32_BitParity(unsigned int N)
260
unsigned int v = N; // word value to compute the parity of
265
return (0x6996 >> v) & 1;
268
#define HAK32_SWAP(a, b) (((a) ^= (b)), ((b) ^= (a)), ((a) ^= (b)))
270
// Return true if the CPU is little endian
271
inline bool Hak32_CPULittleEndian()
274
return ((unsigned char*)&x)[0]? true : false;
277
// http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogObvious
278
// Find the log base 10 of an N-bit integer in O(lg(N))
279
inline unsigned int Hak32_Log2(unsigned int N)
281
unsigned int v = N; // find the log base 2 of 32-bit v
282
int r; // result goes here
284
static const int MultiplyDeBruijnBitPosition[32] =
286
0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
287
31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
290
v |= v >> 1; // first round down to power of 2
297
r = MultiplyDeBruijnBitPosition[static_cast<unsigned int>(v * 0x077CB531UL) >> 27];
301
// http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogObvious
302
// Find the log base 2 of an N-bit integer in O(lg(N))
303
inline unsigned int Hak32_Log10(unsigned int N)
305
unsigned int v = N; // non-zero 32-bit integer value to compute the log base 10 of
306
int r; // result goes here
309
static unsigned int const PowersOf10[] =
310
{1, 10, 100, 1000, 10000, 100000,
311
1000000, 10000000, 100000000, 1000000000};
313
t = (Hak32_Log2(v) + 1) * 1233 >> 12; // (use a lg2 method from above)
314
r = t - (v < PowersOf10[t]);
319
// http://graphics.stanford.edu/~seander/bithacks.html
320
// Count the consecutive zero bits (trailing) on the right by binary search
321
inline unsigned int Hack32_TrailingZeroRight(unsigned int N)
323
unsigned int v = N; // 32-bit word input to count zero bits on right
324
unsigned int c; // c will be the number of zero bits on the right,
325
// so if v is 1101000 (base 2), then c will be 3
326
// NOTE: if 0 == v, then c = 31.
329
// special case for odd v (assumed to happen half of the time)
335
if ((v & 0xffff) == 0)
362
#endif // MATHUTILITY_H