nux-1.16.0
|
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 00073 template<typename T> inline const T Abs (const T &a) 00074 { 00075 return a >= 0 ? a : -a; 00076 } 00078 template<typename T> inline const T &Min (const T &a, const T &b) 00079 { 00080 return a <= b ? a : b; 00081 } 00083 template<typename T> inline const T &Min (const T &a, const T &b, const T &c) 00084 { 00085 return Min<T> (Min<T> (a, b), c); 00086 } 00088 template<typename T> inline const T &Min (const T &a, const T &b, const T &c, const T &d) 00089 { 00090 return Min<T> (Min<T> (Min<T> (a, b), c), d); 00091 } 00093 template<typename T> inline const T &Max (const T &a, const T &b) 00094 { 00095 return a >= b ? a : b; 00096 } 00098 template<typename T> inline const T &Max (const T &a, const T &b, const T &c) 00099 { 00100 return Max<T> (Max<T> (a, b), c); 00101 } 00103 template<typename T> inline const T &Max (const T &a, const T &b, const T &c, const T &d) 00104 { 00105 return Max<T> (Max<T> (a, b, c), d); 00106 } 00107 00108 template<typename T> inline T Max3 (const T A, const T B, const T C) 00109 { 00110 return Max<T> (Max<T> (A, B), C); 00111 } 00112 00113 template<typename T> inline T Min3 (const T A, const T B, const T C) 00114 { 00115 return Min<T> (Min<T> (A, B), C); 00116 } 00117 00119 template<typename T> inline T Sign (const T &x) 00120 { 00121 return (x < 0) ? -1 : (x == 0 ? 0 : 1); 00122 } 00123 00124 00125 template<typename T> inline T Modulo (const T &x, const T &m) 00126 { 00127 return x - m * (T) std::floor ((double) x / m); 00128 } 00129 00130 inline int ModuloInt (const int x, const int m) 00131 { 00132 return x >= 0 ? x % m : (x % m ? m + x % m : 0); 00133 } 00134 00135 template<typename T> inline T MinMod (const T &a, const T &b) 00136 { 00137 return a * b <= 0 ? 0 : (a > 0 ? (a < b ? a : b) : (a < b ? b : a)); 00138 } 00139 00141 00144 inline double Random() 00145 { 00146 return (double) std::rand() / RAND_MAX; 00147 } 00148 00150 00153 inline double CRandom() 00154 { 00155 return 1 - 2 * (std::rand() / RAND_MAX); 00156 } 00157 00159 00162 inline double RandomGaussian() 00163 { 00164 return std::sqrt (-2 * std::log ((double) (1e-10 + (1 - 2e-10) * std::rand()))) * std::cos ((double) (2 * 3.14f/*Const::pi*/*std::rand())); 00165 } 00166 00167 inline unsigned int RandomUInt() 00168 { 00169 return std::rand(); 00170 } 00171 00172 inline unsigned int RandomUInt (unsigned int max_random) 00173 { 00174 return std::rand() % max_random; 00175 } 00176 00177 inline t_size DiffPointer (void *Ptr0, void *Ptr1) 00178 { 00179 if ((t_size) Ptr0 >= (t_size) Ptr1) return (t_size) ((t_size) Ptr0 - (t_size) Ptr1); 00180 00181 return (t_size) ((t_size) Ptr1 - (t_size) Ptr0); 00182 } 00183 // Dangerous to use! 00184 template<typename T> inline T SubstractPointer (void *Ptr, t_size Value) 00185 { 00186 return (T) (((t_size) Ptr) - Value); 00187 } 00188 template<typename T> inline T AddPointer (void *Ptr, t_size Value) 00189 { 00190 return (T) (((t_size) Ptr) + Value); 00191 } 00192 00194 00197 template<typename T> inline T RoundUp (T Value, int Alignment) 00198 { 00199 return (Value + (Alignment - 1)) & ~ (Alignment - 1); 00200 } 00201 00203 00206 template<typename T> inline T RoundDown (T Value, int Alignment) 00207 { 00208 return ((Value) & ~ (Alignment - 1)); 00209 } 00210 00212 00215 template<typename T> inline bool IsAligned (T Value, int Alignment) 00216 { 00217 return (((Value) & ~ (Alignment - 1)) == 0); 00218 } 00219 00224 inline t_u16 ReverseByteOrdering (t_u16 value) 00225 { 00226 t_u16 temp; 00227 t_u8 *src = (t_u8 *) &value; 00228 t_u8 *dest = (t_u8 *) &temp; 00229 00230 dest[0] = src[1]; 00231 dest[1] = src[0]; 00232 00233 return temp; 00234 } 00235 00240 inline t_u32 ReverseByteOrdering (t_u32 value) 00241 { 00242 t_u32 temp; 00243 t_u8 *src = (t_u8 *) &value; 00244 t_u8 *dest = (t_u8 *) &temp; 00245 00246 dest[0] = src[3]; 00247 dest[1] = src[2]; 00248 dest[2] = src[1]; 00249 dest[3] = src[0]; 00250 00251 return temp; 00252 } 00253 00258 inline t_u64 ReverseByteOrdering (t_u64 value) 00259 { 00260 t_u64 temp; 00261 t_u8 *src = (t_u8 *) &value; 00262 t_u8 *dest = (t_u8 *) &temp; 00263 00264 dest[0] = src[7]; 00265 dest[1] = src[6]; 00266 dest[2] = src[5]; 00267 dest[3] = src[4]; 00268 dest[4] = src[3]; 00269 dest[5] = src[2]; 00270 dest[6] = src[1]; 00271 dest[7] = src[0]; 00272 00273 return temp; 00274 } 00275 00276 // Bit Hack 00277 00278 // Determining if an integer is a power of 2 00279 // http://graphics.stanford.edu/~seander/bithacks.html 00280 inline bool IsPowerOf2 (unsigned int n) 00281 { 00282 // The algorithm does not 0 consider 0 a power of two. (this is right) 00283 return ! (n & (n - 1)) && n; 00284 } 00285 00286 // Compute the next highest power of 2 of 32-bit v 00287 // http://graphics.stanford.edu/~seander/bithacks.html 00288 inline unsigned int NextPowerOfTwo (unsigned int x) 00289 { 00290 x = x - 1; 00291 x = x | (x >> 1); 00292 x = x | (x >> 2); 00293 x = x | (x >> 4); 00294 x = x | (x >> 8); 00295 x = x | (x >> 16); 00296 return x + 1; 00297 } 00298 00299 inline unsigned int GetLowerPowerOfTwoExponent (unsigned int x) 00300 { 00301 int count = 0; 00302 00303 while (x > 1) 00304 { 00305 x >>= 1; 00306 count++; 00307 } 00308 00309 return count; 00310 } 00311 00312 inline unsigned int PowerOfTwo (int i) 00313 { 00314 int e = 0; 00315 unsigned int power = 1; 00316 00317 while (e < i) 00318 { 00319 power = power << 1; 00320 e++; 00321 } 00322 00323 return power; 00324 } 00325 00326 // ClearLSBBit(0x01001100) = 0x01001000 00327 inline unsigned int Hak32_ClearLSBBit (unsigned int N) 00328 { 00329 return N & (N - 1); 00330 } 00331 00332 // http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetKernighan 00333 // Hak32_CountNumBits(0x01001100) = 3 00334 inline unsigned int Hak32_CountNumBits (unsigned int N) 00335 { 00336 unsigned int v = N; // count the number of bits set in v 00337 unsigned int c; // c accumulates the total bits set in v 00338 00339 for (c = 0; v; c++) 00340 { 00341 v &= v - 1; // clear the least significant bit set 00342 } 00343 00344 return c; 00345 } 00346 00347 // http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetKernighan : Compute parity in parallel 00348 inline unsigned int Hak32_BitParity (unsigned int N) 00349 { 00350 unsigned int v = N; // word value to compute the parity of 00351 v ^= v >> 16; 00352 v ^= v >> 8; 00353 v ^= v >> 4; 00354 v &= 0xf; 00355 return (0x6996 >> v) & 1; 00356 } 00357 00358 #define HAK32_SWAP(a, b) (((a) ^= (b)), ((b) ^= (a)), ((a) ^= (b))) 00359 00360 // Return true if the CPU is little endian 00361 inline bool Hak32_CPULittleEndian() 00362 { 00363 const int x = 1; 00364 return ((unsigned char *) &x) [0] ? true : false; 00365 } 00366 00367 // http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogObvious 00368 // Find the log base 10 of an N-bit integer in O(lg(N)) 00369 inline unsigned int Hak32_Log2 (unsigned int N) 00370 { 00371 unsigned int v = N; // find the log base 2 of 32-bit v 00372 int r; // result goes here 00373 00374 static const int MultiplyDeBruijnBitPosition[32] = 00375 { 00376 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, 00377 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9 00378 }; 00379 00380 v |= v >> 1; // first round down to power of 2 00381 v |= v >> 2; 00382 v |= v >> 4; 00383 v |= v >> 8; 00384 v |= v >> 16; 00385 v = (v >> 1) + 1; 00386 00387 r = MultiplyDeBruijnBitPosition[static_cast<unsigned int> (v * 0x077CB531UL) >> 27]; 00388 return r; 00389 } 00390 00391 // http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogObvious 00392 // Find the log base 2 of an N-bit integer in O(lg(N)) 00393 inline unsigned int Hak32_Log10 (unsigned int N) 00394 { 00395 unsigned int v = N; // non-zero 32-bit integer value to compute the log base 10 of 00396 int r; // result goes here 00397 int t; // temporary 00398 00399 static unsigned int const PowersOf10[] = 00400 { 00401 1, 10, 100, 1000, 10000, 100000, 00402 1000000, 10000000, 100000000, 1000000000 00403 }; 00404 00405 t = (Hak32_Log2 (v) + 1) * 1233 >> 12; // (use a lg2 method from above) 00406 r = t - (v < PowersOf10[t]); 00407 00408 return r; 00409 } 00410 00411 // http://graphics.stanford.edu/~seander/bithacks.html 00412 // Count the consecutive zero bits (trailing) on the right by binary search 00413 inline unsigned int Hack32_TrailingZeroRight (unsigned int N) 00414 { 00415 unsigned int v = N; // 32-bit word input to count zero bits on right 00416 unsigned int c; // c will be the number of zero bits on the right, 00417 // so if v is 1101000 (base 2), then c will be 3 00418 // NOTE: if 0 == v, then c = 31. 00419 if (v & 0x1) 00420 { 00421 // special case for odd v (assumed to happen half of the time) 00422 c = 0; 00423 } 00424 else 00425 { 00426 c = 1; 00427 00428 if ((v & 0xffff) == 0) 00429 { 00430 v >>= 16; 00431 c += 16; 00432 } 00433 00434 if ((v & 0xff) == 0) 00435 { 00436 v >>= 8; 00437 c += 8; 00438 } 00439 00440 if ((v & 0xf) == 0) 00441 { 00442 v >>= 4; 00443 c += 4; 00444 } 00445 00446 if ((v & 0x3) == 0) 00447 { 00448 v >>= 2; 00449 c += 2; 00450 } 00451 00452 c -= v & 0x1; 00453 } 00454 00455 return c; 00456 } 00457 00458 } 00459 00460 #endif // MATHUTILITY_H