Random.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. #include "Random.h"
  2. #include "Zeit.h"
  3. #include <iostream>
  4. using namespace Framework;
  5. RandomGenerator::RandomGenerator()
  6. {
  7. int tmp[] =
  8. {
  9. 3,
  10. -1726662223, 379960547, 1735697613, 1040273694, 1313901226,
  11. 1627687941, -179304937, -2073333483, 1780058412, -1989503057,
  12. -615974602, 344556628, 939512070, -1249116260, 1507946756,
  13. -812545463, 154635395, 1388815473, -1926676823, 525320961,
  14. -1009028674, 968117788, -123449607, 1284210865, 435012392,
  15. -2017506339, -911064859, -370259173, 1132637927, 1398500161,
  16. -205601318,
  17. };
  18. memcpy( randtbl, tmp, 32 * 4 );
  19. ref = 1;
  20. unsafe_state = {
  21. &randtbl[ 4 ],
  22. &randtbl[ 1 ],
  23. &randtbl[ 1 ],
  24. 3,
  25. 31,
  26. 3,
  27. &randtbl[ 32 ]
  28. };
  29. offset = 0;
  30. srand( (int)time( 0 ) );
  31. }
  32. // Destruktor
  33. RandomGenerator::~RandomGenerator()
  34. {
  35. }
  36. void RandomGenerator::srand( int seed )
  37. {
  38. this->seed = seed;
  39. int type;
  40. int *state;
  41. long int i;
  42. int word;
  43. int *dst;
  44. int kc;
  45. type = unsafe_state.rand_type;
  46. if( (unsigned int)type >= 5 )
  47. return;
  48. state = unsafe_state.state;
  49. if( seed == 0 )
  50. seed = 1;
  51. state[ 0 ] = seed;
  52. if( type == 0 )
  53. return;
  54. dst = state;
  55. word = seed;
  56. kc = unsafe_state.rand_deg;
  57. for( i = 1; i < kc; ++i )
  58. {
  59. long int hi = word / 127773;
  60. long int lo = word % 127773;
  61. word = (int)(16807 * lo - 2836 * hi);
  62. if( word < 0 )
  63. word += 2147483647;
  64. *++dst = word;
  65. }
  66. unsafe_state.fptr = &state[ unsafe_state.rand_sep ];
  67. unsafe_state.rptr = &state[ 0 ];
  68. kc *= 10;
  69. while( --kc >= 0 )
  70. rand();
  71. }
  72. void RandomGenerator::setSeed( __int64 seed )
  73. {
  74. this->offset = 0;
  75. int offset = (int)(seed >> 32);
  76. srand( (int)seed );
  77. offset -= this->offset;
  78. while( offset-- )
  79. rand();
  80. }
  81. double RandomGenerator::rand()
  82. {
  83. offset++;
  84. int *state;
  85. state = unsafe_state.state;
  86. if( unsafe_state.rand_type == 0 )
  87. {
  88. int val = state[ 0 ];
  89. val = ( ( state[ 0 ] * 1103515245 ) + 12345 ) & 0x7fffffff;
  90. state[ 0 ] = val;
  91. return val / 2147483647.0;
  92. }
  93. else
  94. {
  95. int *fptr = unsafe_state.fptr;
  96. int *rptr = unsafe_state.rptr;
  97. int *end_ptr = unsafe_state.end_ptr;
  98. int val;
  99. val = *fptr += *rptr;
  100. int result = ( val >> 1 ) & 0x7fffffff;
  101. ++fptr;
  102. if( fptr >= end_ptr )
  103. {
  104. fptr = state;
  105. ++rptr;
  106. }
  107. else
  108. {
  109. ++rptr;
  110. if( rptr >= end_ptr )
  111. rptr = state;
  112. }
  113. unsafe_state.fptr = fptr;
  114. unsafe_state.rptr = rptr;
  115. double res = result / 2147483647.0;
  116. return res;
  117. }
  118. return 0;
  119. }
  120. __int64 RandomGenerator::getSeed() const
  121. {
  122. __int64 ret = ( (__int64)offset << 32 ) | seed;
  123. return ret;
  124. }
  125. // Erhöht den Reference Counting Zähler.
  126. // return: this.
  127. RandomGenerator *RandomGenerator::getThis()
  128. {
  129. ref++;
  130. return this;
  131. }
  132. // Verringert den Reference Counting Zähler. Wenn der Zähler 0 erreicht, wird das Objekt automatisch gelöscht.
  133. // return: 0.
  134. RandomGenerator *RandomGenerator::release()
  135. {
  136. if( !--ref )
  137. delete this;
  138. return 0;
  139. }