Advertisement
Guest User

xv6 lottery rand.c

a guest
Oct 22nd, 2019
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.75 KB | None | 0 0
  1. /* Period parameters */  
  2. #define N 624
  3. #define M 397
  4. #define MATRIX_A 0x9908b0df   /* constant vector a */
  5. #define UPPER_MASK 0x80000000 /* most significant w-r bits */
  6. #define LOWER_MASK 0x7fffffff /* least significant r bits */
  7.  
  8. /* Tempering parameters */  
  9. #define TEMPERING_MASK_B 0x9d2c5680
  10. #define TEMPERING_MASK_C 0xefc60000
  11. #define TEMPERING_SHIFT_U(y)  (y >> 11)
  12. #define TEMPERING_SHIFT_S(y)  (y << 7)
  13. #define TEMPERING_SHIFT_T(y)  (y << 15)
  14. #define TEMPERING_SHIFT_L(y)  (y >> 18)
  15.  
  16. #define RAND_MAX 0x7fffffff
  17.  
  18. static unsigned long mt[N]; /* the array for the state vector  */
  19. static int mti=N+1; /* mti==N+1 means mt[N] is not initialized */
  20.  
  21. /* initializing the array with a NONZERO seed */
  22. void
  23. sgenrand(unsigned long seed)
  24. {
  25.     /* setting initial seeds to mt[N] using         */
  26.     /* the generator Line 25 of Table 1 in          */
  27.     /* [KNUTH 1981, The Art of Computer Programming */
  28.     /*    Vol. 2 (2nd Ed.), pp102]                  */
  29.     mt[0]= seed & 0xffffffff;
  30.     for (mti=1; mti<N; mti++)
  31.         mt[mti] = (69069 * mt[mti-1]) & 0xffffffff;
  32. }
  33.  
  34. long /* for integer generation */
  35. genrand()
  36. {
  37.     unsigned long y;
  38.     static unsigned long mag01[2]={0x0, MATRIX_A};
  39.     /* mag01[x] = x * MATRIX_A  for x=0,1 */
  40.  
  41.     if (mti >= N) { /* generate N words at one time */
  42.         int kk;
  43.  
  44.         if (mti == N+1)   /* if sgenrand() has not been called, */
  45.             sgenrand(4357); /* a default initial seed is used   */
  46.  
  47.         for (kk=0;kk<N-M;kk++) {
  48.             y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
  49.             mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1];
  50.         }
  51.         for (;kk<N-1;kk++) {
  52.             y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
  53.             mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1];
  54.         }
  55.         y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK);
  56.         mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1];
  57.  
  58.         mti = 0;
  59.     }
  60.  
  61.     y = mt[mti++];
  62.     y ^= TEMPERING_SHIFT_U(y);
  63.     y ^= TEMPERING_SHIFT_S(y) & TEMPERING_MASK_B;
  64.     y ^= TEMPERING_SHIFT_T(y) & TEMPERING_MASK_C;
  65.     y ^= TEMPERING_SHIFT_L(y);
  66.  
  67.     // Strip off uppermost bit because we want a long,
  68.     // not an unsigned long
  69.     return y & RAND_MAX;
  70. }
  71.  
  72. // Assumes 0 <= max <= RAND_MAX
  73. // Returns in the half-open interval [0, max]
  74. long random_at_most(long max) {
  75.   unsigned long
  76.     // max <= RAND_MAX < ULONG_MAX, so this is okay.
  77.     num_bins = (unsigned long) max + 1,
  78.     num_rand = (unsigned long) RAND_MAX + 1,
  79.     bin_size = num_rand / num_bins,
  80.     defect   = num_rand % num_bins;
  81.  
  82.   long x;
  83.   do {
  84.    x = genrand();
  85.   }
  86.   // This is carefully written not to overflow
  87.   while (num_rand - defect <= (unsigned long)x);
  88.  
  89.   // Truncated division is intentional
  90.   return x/bin_size;
  91. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement