nux-0.9.46
|
00001 /* 00002 * Copyright 2010 Inalogic® Inc. 00003 * 00004 * This program is free software: you can redistribute it and/or modify it 00005 * under the terms of the GNU Lesser General Public License, as 00006 * published by the Free Software Foundation; either version 2.1 or 3.0 00007 * of the License. 00008 * 00009 * This program is distributed in the hope that it will be useful, but 00010 * WITHOUT ANY WARRANTY; without even the implied warranties of 00011 * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR 00012 * PURPOSE. See the applicable version of the GNU Lesser General Public 00013 * License for more details. 00014 * 00015 * You should have received a copy of both the GNU Lesser General Public 00016 * License along with this program. If not, see <http://www.gnu.org/licenses/> 00017 * 00018 * Authored by: Jay Taoko <jaytaoko@inalogic.com> 00019 * 00020 */ 00021 00022 00023 #ifndef MATHUTILITY_H 00024 #define MATHUTILITY_H 00025 00026 #include <cstdio> 00027 #include <cstdlib> 00028 #include <cstdarg> 00029 #include <cmath> 00030 #include <cstring> 00031 #include <ctime> 00032 00033 #include "Constants.h" 00034 00035 namespace nux 00036 { 00037 template<typename T> inline T Square (const T A) 00038 { 00039 return A * A; 00040 } 00041 template<typename T> inline T Clamp (const T X, const T min_value, const T max_value) 00042 { 00043 return X < min_value ? min_value : X < max_value ? X : max_value; 00044 } 00045 00046 template<typename T> inline T ClampUp (const T X, const T min_value) 00047 { 00048 return X < min_value ? min_value : X; 00049 } 00050 00051 template<typename T> inline T ClampDown (const T X, const T max_value) 00052 { 00053 return X > max_value ? max_value : X; 00054 } 00055 00056 template<typename T> inline T Align (const T Ptr, int Alignment) 00057 { 00058 return (T) (((NUX_POINTER) Ptr + Alignment - 1) & ~ (Alignment - 1)); 00059 } 00060 00061 //Bitwise rotation on the left. 00062 template<typename T> inline const T Rol (const T &a, const unsigned int n = 1) 00063 { 00064 return (a << n) | (a >> ((sizeof (T) << 3) - n)); 00065 } 00066 //Bitwise rotation on the right. 00067 template<typename T> inline const T Ror (const T &a, const unsigned int n = 1) 00068 { 00069 return (a >> n) | (a << ((sizeof (T) << 3) - n)); 00070 } 00071 00072 // Exchange the values of variables a and b 00073 template<typename T> inline void Swap (T &a, T &b) 00074 { 00075 const T t = a; 00076 a = b; 00077 b = t; 00078 } 00079 template<typename T> inline void Swap (T &a1, T &b1, T &a2, T &b2) 00080 { 00081 Swap (a1, b1); 00082 Swap (a2, b2); 00083 } 00084 template<typename T> inline void Swap (T &a1, T &b1, T &a2, T &b2, T &a3, T &b3) 00085 { 00086 Swap (a1, b1, a2, b2); 00087 Swap (a3, b3); 00088 } 00089 template<typename T> inline void Swap (T &a1, T &b1, T &a2, T &b2, T &a3, T &b3, T &a4, T &b4) 00090 { 00091 Swap (a1, b1, a2, b2, a3, b3); 00092 Swap (a4, b4); 00093 } 00094 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) 00095 { 00096 Swap (a1, b1, a2, b2, a3, b3, a4, b4); 00097 Swap (a5, b5); 00098 } 00099 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) 00100 { 00101 Swap (a1, b1, a2, b2, a3, b3, a4, b4, a5, b5); 00102 Swap (a6, b6); 00103 } 00104 00106 template<typename T> inline const T Abs (const T &a) 00107 { 00108 return a >= 0 ? a : -a; 00109 } 00111 template<typename T> inline const T &Min (const T &a, const T &b) 00112 { 00113 return a <= b ? a : b; 00114 } 00116 template<typename T> inline const T &Min (const T &a, const T &b, const T &c) 00117 { 00118 return Min<T> (Min<T> (a, b), c); 00119 } 00121 template<typename T> inline const T &Min (const T &a, const T &b, const T &c, const T &d) 00122 { 00123 return Min<T> (Min<T> (Min<T> (a, b), c), d); 00124 } 00126 template<typename T> inline const T &Max (const T &a, const T &b) 00127 { 00128 return a >= b ? a : b; 00129 } 00131 template<typename T> inline const T &Max (const T &a, const T &b, const T &c) 00132 { 00133 return Max<T> (Max<T> (a, b), c); 00134 } 00136 template<typename T> inline const T &Max (const T &a, const T &b, const T &c, const T &d) 00137 { 00138 return Max<T> (Max<T> (a, b, c), d); 00139 } 00140 00141 template<typename T> inline T Max3 (const T A, const T B, const T C) 00142 { 00143 return Max<T> (Max<T> (A, B), C); 00144 } 00145 00146 template<typename T> inline T Min3 (const T A, const T B, const T C) 00147 { 00148 return Min<T> (Min<T> (A, B), C); 00149 } 00150 00152 template<typename T> inline T Sign (const T &x) 00153 { 00154 return (x < 0) ? -1 : (x == 0 ? 0 : 1); 00155 } 00156 00157 00158 template<typename T> inline T Modulo (const T &x, const T &m) 00159 { 00160 return x - m * (T) std::floor ((double) x / m); 00161 } 00162 00163 inline int ModuloInt (const int x, const int m) 00164 { 00165 return x >= 0 ? x % m : (x % m ? m + x % m : 0); 00166 } 00167 00168 template<typename T> inline T MinMod (const T &a, const T &b) 00169 { 00170 return a * b <= 0 ? 0 : (a > 0 ? (a < b ? a : b) : (a < b ? b : a)); 00171 } 00172 00174 00177 inline double Random() 00178 { 00179 return (double) std::rand() / RAND_MAX; 00180 } 00181 00183 00186 inline double CRandom() 00187 { 00188 return 1 - 2 * (std::rand() / RAND_MAX); 00189 } 00190 00192 00195 inline double RandomGaussian() 00196 { 00197 return std::sqrt (-2 * std::log ((double) (1e-10 + (1 - 2e-10) * std::rand()))) * std::cos ((double) (2 * 3.14f/*Const::pi*/*std::rand())); 00198 } 00199 00200 inline unsigned int RandomUInt() 00201 { 00202 return std::rand(); 00203 } 00204 00205 inline unsigned int RandomUInt (unsigned int max_random) 00206 { 00207 return std::rand() % max_random; 00208 } 00209 00210 inline t_size DiffPointer (void *Ptr0, void *Ptr1) 00211 { 00212 if ((t_size) Ptr0 >= (t_size) Ptr1) return (t_size) ((t_size) Ptr0 - (t_size) Ptr1); 00213 00214 return (t_size) ((t_size) Ptr1 - (t_size) Ptr0); 00215 } 00216 // Dangerous to use! 00217 template<typename T> inline T SubstractPointer (void *Ptr, t_size Value) 00218 { 00219 return (T) (((t_size) Ptr) - Value); 00220 } 00221 template<typename T> inline T AddPointer (void *Ptr, t_size Value) 00222 { 00223 return (T) (((t_size) Ptr) + Value); 00224 } 00225 00227 00230 template<typename T> inline T RoundUp (T Value, int Alignment) 00231 { 00232 return (Value + (Alignment - 1)) & ~ (Alignment - 1); 00233 } 00234 00236 00239 template<typename T> inline T RoundDown (T Value, int Alignment) 00240 { 00241 return ((Value) & ~ (Alignment - 1)); 00242 } 00243 00245 00248 template<typename T> inline bool IsAligned (T Value, int Alignment) 00249 { 00250 return (((Value) & ~ (Alignment - 1)) == 0); 00251 } 00252 00257 inline t_u16 ReverseByteOrdering (t_u16 value) 00258 { 00259 t_u16 temp; 00260 t_u8 *src = (t_u8 *) &value; 00261 t_u8 *dest = (t_u8 *) &temp; 00262 00263 dest[0] = src[1]; 00264 dest[1] = src[0]; 00265 00266 return temp; 00267 } 00268 00273 inline t_u32 ReverseByteOrdering (t_u32 value) 00274 { 00275 t_u32 temp; 00276 t_u8 *src = (t_u8 *) &value; 00277 t_u8 *dest = (t_u8 *) &temp; 00278 00279 dest[0] = src[3]; 00280 dest[1] = src[2]; 00281 dest[2] = src[1]; 00282 dest[3] = src[0]; 00283 00284 return temp; 00285 } 00286 00291 inline t_u64 ReverseByteOrdering (t_u64 value) 00292 { 00293 t_u64 temp; 00294 t_u8 *src = (t_u8 *) &value; 00295 t_u8 *dest = (t_u8 *) &temp; 00296 00297 dest[0] = src[7]; 00298 dest[1] = src[6]; 00299 dest[2] = src[5]; 00300 dest[3] = src[4]; 00301 dest[4] = src[3]; 00302 dest[5] = src[2]; 00303 dest[6] = src[1]; 00304 dest[7] = src[0]; 00305 00306 return temp; 00307 } 00308 00309 // Bit Hack 00310 00311 // Determining if an integer is a power of 2 00312 // http://graphics.stanford.edu/~seander/bithacks.html 00313 inline bool IsPowerOf2 (unsigned int n) 00314 { 00315 // The algorithm does not 0 consider 0 a power of two. (this is right) 00316 return ! (n & (n - 1)) && n; 00317 } 00318 00319 // Compute the next highest power of 2 of 32-bit v 00320 // http://graphics.stanford.edu/~seander/bithacks.html 00321 inline unsigned int NextPowerOfTwo (unsigned int x) 00322 { 00323 x = x - 1; 00324 x = x | (x >> 1); 00325 x = x | (x >> 2); 00326 x = x | (x >> 4); 00327 x = x | (x >> 8); 00328 x = x | (x >> 16); 00329 return x + 1; 00330 } 00331 00332 inline unsigned int GetLowerPowerOfTwoExponent (unsigned int x) 00333 { 00334 int count = 0; 00335 00336 while (x > 1) 00337 { 00338 x >>= 1; 00339 count++; 00340 } 00341 00342 return count; 00343 } 00344 00345 inline unsigned int PowerOfTwo (int i) 00346 { 00347 int e = 0; 00348 unsigned int power = 1; 00349 00350 while (e < i) 00351 { 00352 power = power << 1; 00353 e++; 00354 } 00355 00356 return power; 00357 } 00358 00359 // ClearLSBBit(0x01001100) = 0x01001000 00360 inline unsigned int Hak32_ClearLSBBit (unsigned int N) 00361 { 00362 return N & (N - 1); 00363 } 00364 00365 // http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetKernighan 00366 // Hak32_CountNumBits(0x01001100) = 3 00367 inline unsigned int Hak32_CountNumBits (unsigned int N) 00368 { 00369 unsigned int v = N; // count the number of bits set in v 00370 unsigned int c; // c accumulates the total bits set in v 00371 00372 for (c = 0; v; c++) 00373 { 00374 v &= v - 1; // clear the least significant bit set 00375 } 00376 00377 return c; 00378 } 00379 00380 // http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetKernighan : Compute parity in parallel 00381 inline unsigned int Hak32_BitParity (unsigned int N) 00382 { 00383 unsigned int v = N; // word value to compute the parity of 00384 v ^= v >> 16; 00385 v ^= v >> 8; 00386 v ^= v >> 4; 00387 v &= 0xf; 00388 return (0x6996 >> v) & 1; 00389 } 00390 00391 #define HAK32_SWAP(a, b) (((a) ^= (b)), ((b) ^= (a)), ((a) ^= (b))) 00392 00393 // Return true if the CPU is little endian 00394 inline bool Hak32_CPULittleEndian() 00395 { 00396 const int x = 1; 00397 return ((unsigned char *) &x) [0] ? true : false; 00398 } 00399 00400 // http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogObvious 00401 // Find the log base 10 of an N-bit integer in O(lg(N)) 00402 inline unsigned int Hak32_Log2 (unsigned int N) 00403 { 00404 unsigned int v = N; // find the log base 2 of 32-bit v 00405 int r; // result goes here 00406 00407 static const int MultiplyDeBruijnBitPosition[32] = 00408 { 00409 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, 00410 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9 00411 }; 00412 00413 v |= v >> 1; // first round down to power of 2 00414 v |= v >> 2; 00415 v |= v >> 4; 00416 v |= v >> 8; 00417 v |= v >> 16; 00418 v = (v >> 1) + 1; 00419 00420 r = MultiplyDeBruijnBitPosition[static_cast<unsigned int> (v * 0x077CB531UL) >> 27]; 00421 return r; 00422 } 00423 00424 // http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogObvious 00425 // Find the log base 2 of an N-bit integer in O(lg(N)) 00426 inline unsigned int Hak32_Log10 (unsigned int N) 00427 { 00428 unsigned int v = N; // non-zero 32-bit integer value to compute the log base 10 of 00429 int r; // result goes here 00430 int t; // temporary 00431 00432 static unsigned int const PowersOf10[] = 00433 { 00434 1, 10, 100, 1000, 10000, 100000, 00435 1000000, 10000000, 100000000, 1000000000 00436 }; 00437 00438 t = (Hak32_Log2 (v) + 1) * 1233 >> 12; // (use a lg2 method from above) 00439 r = t - (v < PowersOf10[t]); 00440 00441 return r; 00442 } 00443 00444 // http://graphics.stanford.edu/~seander/bithacks.html 00445 // Count the consecutive zero bits (trailing) on the right by binary search 00446 inline unsigned int Hack32_TrailingZeroRight (unsigned int N) 00447 { 00448 unsigned int v = N; // 32-bit word input to count zero bits on right 00449 unsigned int c; // c will be the number of zero bits on the right, 00450 // so if v is 1101000 (base 2), then c will be 3 00451 // NOTE: if 0 == v, then c = 31. 00452 if (v & 0x1) 00453 { 00454 // special case for odd v (assumed to happen half of the time) 00455 c = 0; 00456 } 00457 else 00458 { 00459 c = 1; 00460 00461 if ((v & 0xffff) == 0) 00462 { 00463 v >>= 16; 00464 c += 16; 00465 } 00466 00467 if ((v & 0xff) == 0) 00468 { 00469 v >>= 8; 00470 c += 8; 00471 } 00472 00473 if ((v & 0xf) == 0) 00474 { 00475 v >>= 4; 00476 c += 4; 00477 } 00478 00479 if ((v & 0x3) == 0) 00480 { 00481 v >>= 2; 00482 c += 2; 00483 } 00484 00485 c -= v & 0x1; 00486 } 00487 00488 return c; 00489 } 00490 00491 } 00492 00493 #endif // MATHUTILITY_H