00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <spl/types.h>
00018
00019 #ifdef _WINDOWS
00020 #include <spl/configwin32.h>
00021 #else
00022 #include <spl/autoconf/config.h>
00023 #endif
00024
00025 #ifdef HAVE_TIME_H
00026 #include <time.h>
00027 #endif
00028 #ifdef HAVE_SYS_TIME_H
00029 #include <sys/time.h>
00030 #endif
00031 #include <math.h>
00032
00033 #include <spl/math/Random.h>
00034
00035 #define RAND_MAX_COMBO (4294967295.0/2)
00036
00037 Random::Random()
00038 {
00039 combo_x = 3;
00040 combo_y = 1;
00041 combo_z = 1;
00042 combo_v = 0;
00043
00044 uint32 seed;
00045
00046 time_t _t;
00047 time (&_t);
00048 seed = ((long)_t) & (((long)_t) << 16) & ((long)_t) & (((long)_t) << 16);
00049 combo_x = seed * 8 + 3;
00050 combo_y = seed * 2 + 1;
00051 combo_z = seed | 1;
00052 combo_v = 0;
00053 }
00054
00055 Random::Random(int seed)
00056 {
00057 combo_x = seed * 8 + 3;
00058 combo_y = seed * 2 + 1;
00059 combo_z = seed | 1;
00060 combo_v = 0;
00061 }
00062
00063 int Random::Next()
00064 {
00065 combo_v = combo_x * combo_y;
00066 combo_x = combo_y;
00067 combo_y = combo_v;
00068 combo_z = (combo_z & 65535L) * 30903 + (combo_z >> 16);
00069 int rnd = combo_y + combo_z;
00070 if ( rnd < 0 )
00071 {
00072 return -1 * rnd;
00073 }
00074 return rnd;
00075 }
00076
00077 int Random::Next(int max)
00078 {
00079 return Next() % max;
00080 }
00081
00082 int Random::Next(int min, int max)
00083 {
00084 return (int)(NextDouble() * (max - min) + min);
00085 }
00086
00087 double Random::NextDouble()
00088 {
00089 double val = fabs((double)Next()/(double)RAND_MAX_COMBO);
00090 ASSERT( val <= 1.0 );
00091 return val;
00092 }
00093
00094 void Random::NextBytes(byte *data, int len)
00095 {
00096 for ( int x = 0; x < len; x++ )
00097 {
00098 int next = Next(256);
00099 ASSERT (next < 256);
00100 data[x] = (byte)next;
00101 }
00102 }
00103
00104 int Random::NextInt()
00105 {
00106 combo_v = combo_x * combo_y;
00107 combo_x = combo_y;
00108 combo_y = combo_v;
00109 combo_z = (combo_z & 65535L) * 30903 + (combo_z >> 16);
00110 return combo_y + combo_z;
00111 }