• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

spl/math/Math.h

00001 /*
00002  *   This file is part of the Standard Portable Library (SPL).
00003  *
00004  *   SPL is free software: you can redistribute it and/or modify
00005  *   it under the terms of the GNU General Public License as published by
00006  *   the Free Software Foundation, either version 3 of the License, or
00007  *   (at your option) any later version.
00008  *
00009  *   SPL is distributed in the hope that it will be useful,
00010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *   GNU General Public License for more details.
00013  *
00014  *   You should have received a copy of the GNU General Public License
00015  *   along with SPL.  If not, see <http://www.gnu.org/licenses/>.
00016  */
00017 #ifndef _math_h
00018 #define _math_h
00019 
00020 #include <spl/types.h>
00021 #include <spl/Debug.h>
00022 
00023 #ifdef _WINDOWS
00024 #include <spl/configwin32.h>
00025 #else
00026 #include <spl/autoconf/config.h>
00027 #endif
00028 
00029 #include <math.h>
00030 #include <float.h>
00031 #include <stdlib.h>
00032 #include <spl/Decimal.h>
00033 #include <spl/Exception.h>
00034 
00040 #ifdef __TANDEM
00041 /* Stupid tandem doesn't support standard float functions. */
00042 #define finite(d) (!isnan(d))
00043 #define fabsf fabs
00044 #define acosf acos
00045 #define asinf asin
00046 #define atanf atan
00047 #define atan2f atan2
00048 #define ceilf ceil
00049 #define cosf cos
00050 #define coshf cosh
00051 #define expf exp
00052 #define floorf floor
00053 #define fmodf fmod
00054 #define logf log
00055 #define log10f log10
00056 #define powf pow
00057 #define sinf sin
00058 #define sinhf sinh
00059 #define sqrtf sqrt
00060 #define tanf tan
00061 #define tanhf tanh
00062 #endif
00063 
00068 class Math
00069 {
00070 private:
00071         static uint32 combo_x;
00072         static uint32 combo_y;
00073         static uint32 combo_z;
00074         static uint32 combo_v;
00075         static bool gInited;
00076         
00077 public:
00078         inline static double E() { return 2.71828182845904523536; }
00079         inline static double PI() { return 3.14159265358979323846; }
00080 
00081         inline static bool IsINF(double d) 
00082         {
00083 #if defined(WIN32) || defined(_WIN32) 
00084                 return _finite(d) == 0;
00085 #else
00086                 return finite(d) == 0;
00087 #endif 
00088         }
00089 
00090         inline static bool IsNaN(double d) 
00091         { 
00092 #ifdef _WINDOWS
00093                 return _isnan(d) != 0; 
00094 #else
00095                 return isnan(d) != 0; 
00096 #endif
00097         }
00098 
00099         inline static int Abs(int8 i) { return abs(i); }
00100         inline static int16 Abs(int16 i) { return abs(i); }
00101         inline static int32 Abs(int32 i) { return abs(i); }
00102         inline static int64 Abs(int64 i) 
00103         { 
00104 #ifdef _WINDOWS
00105 #if _MSC_VER > 1200
00106                 return _abs64(i);
00107 #else
00108                 return i < 0 ? -i : i;
00109 #endif
00110 #else
00111                 return labs(i); 
00112 #endif
00113         }
00114         inline static float32 Abs(float32 f) { return fabsf(f); }
00115         inline static float64 Abs(float64 f) { return fabs(f); }
00116         inline static Decimal Abs(Decimal d) { return d.Abs(); }
00117         inline static double Acos(double f) { return acos(f); }
00118         inline static float Acos(float f) { return acosf(f); }
00119         inline static double Asin(double f) { return asin(f); }
00120         inline static float Asin(float f) { return asinf(f); }
00121         inline static double Atan(double f) { return atan(f); }
00122         inline static float Atan(float f) { return atanf(f); }
00123         inline static double Atan2(double x, double y) { return atan2(x, y); }
00124         inline static float Atan2(float x, float y) { return atan2f(x, y); }
00125         inline static double Ceiling(double f) { return ceil(f); }
00126         inline static float Ceiling(float f) { return ceilf(f); }
00127         inline static double Cos(double f) { return cos(f); }
00128         inline static float Cos(float f) { return cosf(f); }
00129         inline static double Cosh(double f) { return cosh(f); }
00130         inline static float Cosh(float f) { return coshf(f); }
00131         inline static double Exp(double d) { return exp(d); }
00132         inline static float Exp(float d) { return expf(d); }
00133         inline static double Floor(double f) { return floor(f); }
00134         inline static float Floor(float f) { return floorf(f); }
00135         inline static double Remainder(double x, double y) { return fmod(x, y); }
00136         inline static float Remainder(float x, float y) { return fmodf(x, y); }
00137         inline static double Log(double d) { return log(d); }
00138         inline static float Log(float d) { return logf(d); }
00139         inline static double Log(double d, double base) { return log(d)/log(base); }
00140         inline static float Log(float d, float base) { return logf(d)/logf(base); }
00141         inline static double Log10(double d) { return log10(d); }
00142         inline static float Log10(float d) { return log10f(d); }
00143         inline static int8 Max(int8 a, int8 b) { return (a>b) ? a : b; }
00144         inline static byte Max(byte a, byte b) { return (a>b) ? a : b; }
00145         inline static int16 Max(int16 a, int16 b) { return (a>b) ? a : b; }
00146         inline static uint16 Max(uint16 a, uint16 b) { return (a>b) ? a : b; }
00147         inline static int32 Max(int32 a, int32 b) { return (a>b) ? a : b; }
00148         inline static uint32 Max(uint32 a, uint32 b) { return (a>b) ? a : b; }
00149         inline static int64 Max(int64 a, int64 b) { return (a>b) ? a : b; }
00150 #ifndef __TANDEM
00151         inline static uint64 Max(uint64 a, uint64 b) { return (a>b) ? a : b; }
00152 #endif
00153         inline static float32 Max(float32 a, float32 b) { return (a>b) ? a : b; }
00154         inline static double Max(double a, double b) { return (a>b) ? a : b; }
00155         inline static Decimal Max(Decimal a, Decimal b) { return (a>b) ? a : b; }
00156         inline static int8 Min(int8 a, int8 b) { return (a<b) ? a : b; }
00157         inline static byte Min(byte a, byte b) { return (a<b) ? a : b; }
00158         inline static int16 Min(int16 a, int16 b) { return (a<b) ? a : b; }
00159         inline static uint16 Min(uint16 a, uint16 b) { return (a<b) ? a : b; }
00160         inline static int32 Min(int32 a, int32 b) { return (a<b) ? a : b; }
00161         inline static uint32 Min(uint32 a, uint32 b) { return (a<b) ? a : b; }
00162         inline static int64 Min(int64 a, int64 b) { return (a<b) ? a : b; }
00163 #ifndef __TANDEM
00164         inline static uint64 Min(uint64 a, uint64 b) { return (a<b) ? a : b; }
00165 #endif
00166         inline static float32 Min(float32 a, float32 b) { return (a<b) ? a : b; }
00167         inline static double Min(double a, double b) { return (a<b) ? a : b; }
00168         inline static Decimal Min(Decimal a, Decimal b) { return (a<b) ? a : b; }
00169         inline static double Pow(double d, double e) { return pow(d, e); }
00170         inline static float Pow(float d, float e) { return powf(d, e); }
00171         inline static double Round(double d) { return (double)((int64)d); }
00172         inline static float Round(float d) { return (float)((int64)d); }
00173         inline static double Round(double d, int dec) { double r = pow(10.0, dec); return floor(d*r)/r; }
00174         inline static float Round(float d, int dec) { double r = pow(10.0, dec); return (float)(floor(d*r)/r); }
00175         inline static Decimal Round(Decimal d) { return d.Round(); }
00176         inline static int Sign(int8 i) { return (i) ? ((i>0)?1:-1) : 0; }
00177         inline static int Sign(int16 i) { return (i) ? ((i>0)?1:-1) : 0; }
00178         inline static int Sign(int32 i) { return (i) ? ((i>0)?1:-1) : 0; }
00179         inline static int Sign(int64 i) { return (i) ? ((i>0)?1:-1) : 0; }
00180         inline static int Sign(float32 f) { return (f) ? ((f>0)?1:-1) : 0; }
00181         inline static int Sign(double d) { return (d) ? ((d>0)?1:-1) : 0; }
00182         inline static int Sign(Decimal d) { return (d.RawData()) ? ((d.RawData()>0)?1:-1) : 0; }
00183         inline static double Sin(double d) { return sin(d); }
00184         inline static float Sin(float d) { return sinf(d); }
00185         inline static double Sinh(double d) { return sinh(d); }
00186         inline static float Sinh(float d) { return sinhf(d); }
00187         inline static double Sqrt(double d) { return sqrt(d); }
00188         inline static float Sqrt(float d) { return sqrtf(d); }
00189         inline static double Tan(double d) { return tan(d); }
00190         inline static float Tan(float d) { return tanf(d); }
00191         inline static double Tanh(double d) { return tanh(d); }
00192         inline static float Tanh(float d) { return tanhf(d); }
00193 
00194         static void InitRandom();
00195         static double Random();
00196         static int RandomInt();
00197         inline static int RandomRange(int max) { return (int)(Random() * max); }
00198         
00199         static bool IsPrime( const int n );
00200         static int NextPrime( const int n );
00201         
00202         inline static int32 Hash( const int64 i ) { return (int32)((i >> 32) ^ (i && 0XFFFFFFFF)); }
00203         inline static int32 Hash( const int32 i ) { return i; }
00204         inline static int32 Hash( const int16 i ) { return i | (i << 16); }
00205         inline static int32 Hash( const int8 i ) { return i | (i << 8) | (i << 16) | (i << 24); }
00206         inline static int32 Hash( const uint64 i ) { return (int32)((i >> 32) ^ (i && 0XFFFFFFFF)); }
00207         inline static int32 Hash( const uint32 i ) { return i; }
00208         inline static int32 Hash( const uint16 i ) { return i | (i << 16); }
00209         inline static int32 Hash( const uint8 i ) { return i | (i << 8) | (i << 16) | (i << 24); }
00210         static int32 Hash( const float32 i );
00211         static int32 Hash( const float64 i );
00212         static int32 Hash( const char *cp );
00213         static int32 Hash( const IHashable& i );
00214         static int32 Hash( const IHashable *i );
00215 };
00216 
00220 class FastMath
00221 {
00222 protected:
00223         static float64 m_sinus[4096];
00224         static float64 m_cosinus[4096];
00225         static bool m_trig;
00226         static float64 m_pi;
00227         static float64 m_rad2scale;
00228         static float64 m_pad;
00229 
00230         static int m_fastRandoms[32];
00231         static int m_fastRndPointer;
00232         static bool m_fastRndInit;
00233 
00234         static float32 InvSqrt(float32 x);
00235         static void BuildTrig();
00236 
00237 public:
00238         inline static float32 Sqrt(float32 x)
00239         {
00240             return 1.0f / InvSqrt(x);
00241         }
00242 
00243         inline static float64 Sqrt(float64 x)
00244         {
00245                 return Math::Sqrt(x);
00246         }
00247 
00248         static inline float64 Deg2rad(float64 deg)
00249         {
00250                 return deg * 0.0174532925194f;
00251         }
00252 
00253         static inline float64 Rad2deg(float64 rad)
00254         {
00255                 return rad * 57.295779514719f;
00256         }
00257 
00258         static inline float64 Sin(float64 angle)
00259         {
00260                 if(!m_trig) BuildTrig();
00261                 return m_sinus[(int)((angle+m_pad)*m_rad2scale)&0xFFF];
00262         }
00263 
00264         static inline float64 Cos(float64 angle)
00265         {
00266                 if(!m_trig) BuildTrig();
00267                 return m_cosinus[(int)((angle+m_pad)*m_rad2scale)&0xFFF];
00268         }
00269 
00270         static inline float64 Pythagoras(float64 a, float64 b)
00271         {
00272                 return Sqrt(a*a+b*b);
00273         }
00274 
00275         static inline int Pythagoras(int a, int b)
00276         {
00277                 return (int)Sqrt((float64)(a*a+b*b));
00278         }
00279 
00280         // R A N G E  T O O L S
00281 
00282         static inline int Crop(int num, int min, int max)
00283         {
00284                 return (num<min) ? min : (num>max) ? max : num;
00285         }
00286 
00287         static inline float64 Crop(float64 num, float64 min, float64 max)
00288         {
00289                 return (num<min) ? min : (num>max) ? max : num;
00290         }
00291 
00292         static inline bool InRange(int num, int min, int max)
00293         {
00294                 return ((num>=min) && (num<max));
00295         }
00296 
00297         // B U F F E R   O P E R A T I O N S
00298 
00299         static inline void ClearBuffer(int *buffer, int size, int value)
00300         {
00301                 memset(buffer, value, sizeof(int)*size);
00302         }
00303 
00304         static void CropBuffer(int *buffer, int size, int min, int max);
00305 
00306         static inline void CopyBuffer(int *source, int size, int *target)
00307         {
00308                 memcpy(target, source, size*sizeof(int));
00309         }
00310 
00311         // R A N D O M  N U M B E R S
00312 
00313         static inline float64 Random()
00314         {
00315                 return (float64)(Math::Random());
00316         }
00317 
00318         static inline float64 Random(float64 min, float64 max)
00319         {
00320                 return (float64)(Math::Random()*(max-min)+min);
00321         }
00322 
00323         static inline float64 RandomWithDelta(float64 averidge, float64 delta)
00324         {
00325                 return averidge + Random() * delta;
00326         }
00327 
00328         static int FastRandom(int bits);
00329 
00330         static inline int FastRndBit()
00331         {
00332                 return FastRandom(1);
00333         }
00334 
00335         static inline float64 Interpolate(float64 a, float64 b, float64 d)
00336         {
00337                 float64 f = (1-Cos(d*m_pi))*0.5f;
00338                 return a+f*(b-a);
00339         }
00340         
00341         inline bool IsPrime( const int n ) { return Math::IsPrime(n); }
00342         inline int NextPrime( const int n ) {   return Math::NextPrime(n); }
00343 };
00344 
00347 #endif