Random.cpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. #include "Random.h"
  2. #include "Zeit.h"
  3. #include <iostream>
  4. using namespace Framework;
  5. RandomGenerator::RandomGenerator()
  6. : ReferenceCounter()
  7. {
  8. int tmp[] =
  9. {
  10. 3,
  11. -1726662223, 379960547, 1735697613, 1040273694, 1313901226,
  12. 1627687941, -179304937, -2073333483, 1780058412, -1989503057,
  13. -615974602, 344556628, 939512070, -1249116260, 1507946756,
  14. -812545463, 154635395, 1388815473, -1926676823, 525320961,
  15. -1009028674, 968117788, -123449607, 1284210865, 435012392,
  16. -2017506339, -911064859, -370259173, 1132637927, 1398500161,
  17. -205601318,
  18. };
  19. memcpy( randtbl, tmp, 32 * 4 );
  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. void RandomGenerator::srand( int seed )
  36. {
  37. this->seed = seed;
  38. int type;
  39. int *state;
  40. long int i;
  41. int word;
  42. int *dst;
  43. int kc;
  44. type = unsafe_state.rand_type;
  45. if( (unsigned int)type >= 5 )
  46. return;
  47. state = unsafe_state.state;
  48. if( seed == 0 )
  49. seed = 1;
  50. state[ 0 ] = seed;
  51. if( type == 0 )
  52. return;
  53. dst = state;
  54. word = seed;
  55. kc = unsafe_state.rand_deg;
  56. for( i = 1; i < kc; ++i )
  57. {
  58. long int hi = word / 127773;
  59. long int lo = word % 127773;
  60. word = (int)( 16807 * lo - 2836 * hi );
  61. if( word < 0 )
  62. word += 2147483647;
  63. *++dst = word;
  64. }
  65. unsafe_state.fptr = &state[ unsafe_state.rand_sep ];
  66. unsafe_state.rptr = &state[ 0 ];
  67. kc *= 10;
  68. while( --kc >= 0 )
  69. rand();
  70. }
  71. void RandomGenerator::setSeed( __int64 seed )
  72. {
  73. this->offset = 0;
  74. int offset = (int)( seed >> 32 );
  75. srand( (int)seed );
  76. offset -= this->offset;
  77. while( offset-- > 0 )
  78. rand();
  79. }
  80. double RandomGenerator::rand()
  81. {
  82. offset++;
  83. int *state;
  84. state = unsafe_state.state;
  85. if( unsafe_state.rand_type == 0 )
  86. {
  87. int val = state[ 0 ];
  88. val = ( ( state[ 0 ] * 1103515245 ) + 12345 ) & 0x7fffffff;
  89. state[ 0 ] = val;
  90. return val / 2147483647.0;
  91. }
  92. else
  93. {
  94. int *fptr = unsafe_state.fptr;
  95. int *rptr = unsafe_state.rptr;
  96. int *end_ptr = unsafe_state.end_ptr;
  97. int val;
  98. val = *fptr += *rptr;
  99. int result = ( val >> 1 ) & 0x7fffffff;
  100. ++fptr;
  101. if( fptr >= end_ptr )
  102. {
  103. fptr = state;
  104. ++rptr;
  105. }
  106. else
  107. {
  108. ++rptr;
  109. if( rptr >= end_ptr )
  110. rptr = state;
  111. }
  112. unsafe_state.fptr = fptr;
  113. unsafe_state.rptr = rptr;
  114. double res = result / 2147483647.0;
  115. return res;
  116. }
  117. return 0;
  118. }
  119. __int64 RandomGenerator::getSeed() const
  120. {
  121. __int64 ret = ( (__int64)offset << 32 ) | seed;
  122. return ret;
  123. }