00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifdef _WIN32
00018 #include <spl/configwin32.h>
00019 #else
00020 #include <spl/autoconf/config.h>
00021 #endif
00022
00023 #ifdef HAVE_TIME_H
00024 #include <time.h>
00025 #endif
00026 #ifdef HAVE_SYS_TIME_H
00027 #include <sys/time.h>
00028 #endif
00029
00030 #include <spl/math/Math.h>
00031
00032 uint32 Math::combo_x = 3;
00033 uint32 Math::combo_y = 1;
00034 uint32 Math::combo_z = 1;
00035 uint32 Math::combo_v = 0;
00036 bool Math::gInited = false;
00037
00038 #define RAND_MAX_COMBO (4294967295.0/2)
00039
00040 IHashable::~IHashable()
00041 {
00042 }
00043
00044 IComparable::~IComparable()
00045 {
00046 }
00047
00048 IMemoryValidate::~IMemoryValidate()
00049 {
00050 }
00051
00052 void Math::InitRandom()
00053 {
00054 uint32 seed;
00055
00056 time_t _t;
00057 time (&_t);
00058 seed = ((long)_t) & (((long)_t) << 16) & ((long)_t) & (((long)_t) << 16);
00059 combo_x = seed * 8 + 3;
00060 combo_y = seed * 2 + 1;
00061 combo_z = seed | 1;
00062 combo_v = 0;
00063 }
00064
00065 double Math::Random()
00066 {
00067 return fabs((double)(RandomInt())/(double)RAND_MAX_COMBO);
00068 }
00069
00070 int Math::RandomInt()
00071 {
00072 if ( ! gInited )
00073 {
00074 InitRandom();
00075 }
00076 combo_v = combo_x * combo_y;
00077 combo_x = combo_y;
00078 combo_y = combo_v;
00079 combo_z = (combo_z & 65535L) * 30903 + (combo_z >> 16);
00080 return combo_y + combo_z;
00081 }
00082
00083
00084
00085 bool Math::IsPrime( const int n )
00086 {
00087 if( n == 2 || n == 3 )
00088 {
00089 return true;
00090 }
00091 if( n == 1 || n % 2 == 0 )
00092 {
00093 return false;
00094 }
00095 for( int i = 3; i * i <= n; i += 2 )
00096 {
00097 if( n % i == 0 )
00098 {
00099 return false;
00100 }
00101 }
00102 return true;
00103 }
00104
00105
00106
00107 int Math::NextPrime( const int n )
00108 {
00109 int prime = n;
00110 if( prime % 2 == 0 )
00111 {
00112 prime++;
00113 }
00114 for( ; !IsPrime( prime ); prime += 2 )
00115 {
00116 }
00117 return prime;
00118 }
00119
00120 int32 Math::Hash( const float32 i )
00121 {
00122 double fractpart, intpart;
00123 fractpart = modf (i, &intpart);
00124
00125 return ( ((int)intpart ) ^ (int)(fractpart * 100000) );
00126 }
00127
00128 int32 Math::Hash( const float64 i )
00129 {
00130 double fractpart, intpart;
00131 fractpart = modf (i, &intpart);
00132
00133 return ( ((int)intpart ) ^ (int)(fractpart * 100000) );
00134 }
00135
00136 int32 Math::Hash( const char *str )
00137 {
00138 int len = (int)strlen(str);
00139 int x;
00140 int hash = 0;
00141 int lenmod4 = len % 4;
00142 int part;
00143
00144 ASSERT( (len - lenmod4)%4 == 0 );
00145 for ( x = 0; x < len - lenmod4; x+=4 )
00146 {
00147 part = str[x];
00148
00149
00150 part |= (int)str[x+1] << 8;
00151
00152
00153 part |= (int)str[x+2] << 16;
00154
00155
00156 part |= (int)str[x+3] << 24;
00157
00158 hash ^= part;
00159 }
00160 part = 0;
00161 if ( lenmod4 > 2 )
00162 {
00163
00164 part |= (int)str[len-3];
00165 }
00166 if ( lenmod4 > 1 )
00167 {
00168
00169 part |= (int)str[len-2];
00170 }
00171 if ( lenmod4 > 0 )
00172 {
00173
00174 part |= (int)str[len-1];
00175 hash ^= part;
00176 }
00177 if ( hash < 0 )
00178 {
00179 return -hash;
00180 }
00181 return hash;
00182 }
00183
00184 int32 Math::Hash( const IHashable& i)
00185 {
00186 return i.HashCode();
00187 }
00188
00189 int32 Math::Hash( const IHashable *i)
00190 {
00191 return i->HashCode();
00192 }
00193
00194 float32 FastMath::InvSqrt(float32 x)
00195 {
00196
00197
00198
00199
00200
00201
00202
00203
00204 union { int i; float32 x; } tmp;
00205 float32 xhalf = 0.5f * x;
00206 tmp.x = x;
00207 tmp.i = 0x5f375a86 - (tmp.i >> 1);
00208 x = tmp.x;
00209 x = x * (1.5f - xhalf * x * x);
00210 return x;
00211 }
00212
00213 float64 FastMath::m_sinus[4096];
00214 float64 FastMath::m_cosinus[4096];
00215 bool FastMath::m_trig = false;
00216 float64 FastMath::m_rad2scale = 4096.0 / Math::PI() / 2.0;
00217 float64 FastMath::m_pad = 256 * Math::PI();
00218
00219 int FastMath::m_fastRandoms[32];
00220 int FastMath::m_fastRndPointer = 0;
00221 bool FastMath::m_fastRndInit = false;
00222
00223 void FastMath::BuildTrig()
00224 {
00225 for (int i = 0; i < 4096; i++)
00226 {
00227 m_sinus[i] = Math::Sin((float64) (i / m_rad2scale));
00228 m_cosinus[i] = Math::Cos((float64) (i / m_rad2scale));
00229 }
00230 m_trig = true;
00231 }
00232
00233 void FastMath::CropBuffer(int *buffer, int size, int min, int max)
00234 {
00235 for (int i = size - 1; i >= 0; i--)
00236 {
00237 buffer[i] = Crop(buffer[i], min, max);
00238 }
00239 }
00240
00241 int FastMath::FastRandom(int bits)
00242 {
00243 if ( bits < 1 )
00244 return 0;
00245 m_fastRndPointer = (m_fastRndPointer+1) & 31;
00246 if (!m_fastRndInit)
00247 {
00248 for (int i=0;i<32;i++)
00249 {
00250 m_fastRandoms[i] = (int)Random(0,0xFFFFFF);
00251 }
00252 m_fastRndInit = true;
00253 }
00254 return m_fastRandoms[m_fastRndPointer]&(1<<(bits-1));
00255 }