Back to index

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