00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
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
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
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
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
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