123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155 |
- #include "Random.h"
- #include "Zeit.h"
- #include <iostream>
- using namespace Framework;
- RandomGenerator::RandomGenerator()
- {
- int tmp[] =
- {
- 3,
- -1726662223, 379960547, 1735697613, 1040273694, 1313901226,
- 1627687941, -179304937, -2073333483, 1780058412, -1989503057,
- -615974602, 344556628, 939512070, -1249116260, 1507946756,
- -812545463, 154635395, 1388815473, -1926676823, 525320961,
- -1009028674, 968117788, -123449607, 1284210865, 435012392,
- -2017506339, -911064859, -370259173, 1132637927, 1398500161,
- -205601318,
- };
- memcpy( randtbl, tmp, 32 * 4 );
- ref = 1;
- unsafe_state = {
- &randtbl[ 4 ],
- &randtbl[ 1 ],
- &randtbl[ 1 ],
- 3,
- 31,
- 3,
- &randtbl[ 32 ]
- };
- offset = 0;
- srand( (int)time( 0 ) );
- }
- // Destruktor
- RandomGenerator::~RandomGenerator()
- {
- }
- void RandomGenerator::srand( int seed )
- {
- this->seed = seed;
- int type;
- int *state;
- long int i;
- int word;
- int *dst;
- int kc;
- type = unsafe_state.rand_type;
- if( (unsigned int)type >= 5 )
- return;
- state = unsafe_state.state;
- if( seed == 0 )
- seed = 1;
- state[ 0 ] = seed;
- if( type == 0 )
- return;
- dst = state;
- word = seed;
- kc = unsafe_state.rand_deg;
- for( i = 1; i < kc; ++i )
- {
- long int hi = word / 127773;
- long int lo = word % 127773;
- word = (int)(16807 * lo - 2836 * hi);
- if( word < 0 )
- word += 2147483647;
- *++dst = word;
- }
- unsafe_state.fptr = &state[ unsafe_state.rand_sep ];
- unsafe_state.rptr = &state[ 0 ];
- kc *= 10;
- while( --kc >= 0 )
- rand();
- }
- void RandomGenerator::setSeed( __int64 seed )
- {
- this->offset = 0;
- int offset = (int)(seed >> 32);
- srand( (int)seed );
- offset -= this->offset;
- while( offset-- )
- rand();
- }
- double RandomGenerator::rand()
- {
- offset++;
- int *state;
- state = unsafe_state.state;
- if( unsafe_state.rand_type == 0 )
- {
- int val = state[ 0 ];
- val = ( ( state[ 0 ] * 1103515245 ) + 12345 ) & 0x7fffffff;
- state[ 0 ] = val;
- return val / 2147483647.0;
- }
- else
- {
- int *fptr = unsafe_state.fptr;
- int *rptr = unsafe_state.rptr;
- int *end_ptr = unsafe_state.end_ptr;
- int val;
- val = *fptr += *rptr;
- int result = ( val >> 1 ) & 0x7fffffff;
- ++fptr;
- if( fptr >= end_ptr )
- {
- fptr = state;
- ++rptr;
- }
- else
- {
- ++rptr;
- if( rptr >= end_ptr )
- rptr = state;
- }
- unsafe_state.fptr = fptr;
- unsafe_state.rptr = rptr;
- double res = result / 2147483647.0;
- return res;
- }
- return 0;
- }
- __int64 RandomGenerator::getSeed() const
- {
- __int64 ret = ( (__int64)offset << 32 ) | seed;
- return ret;
- }
- // Erhöht den Reference Counting Zähler.
- // return: this.
- RandomGenerator *RandomGenerator::getThis()
- {
- ref++;
- return this;
- }
- // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Objekt automatisch gelöscht.
- // return: 0.
- RandomGenerator *RandomGenerator::release()
- {
- if( !--ref )
- delete this;
- return 0;
- }
|