Code Snippets

  

C++ Source Code


Welcome to Dream.In.Code
Become a C++ Expert!

Join 149,619 C++ Programmers for FREE! Get instant access to thousands of C++ experts, tutorials, code snippets, and more! There are 1,879 people online right now. Registration is fast and FREE... Join Now!





Better Random Number Class

A powerful pseudorandom number generator wrapped in a user friendly class. Designed as a replacement for rand().

Submitted By: Voodoo Doll
Actions:
Rating:
Views: 8,113

Language: C++

Last Modified: January 24, 2006

Snippet


  1. /*
  2.   Random number generator class
  3.   =============================
  4.   History:
  5.   Created - Sarah "Voodoo Doll" White (2006/01/24)
  6.   =============================
  7.   Description:
  8.   This class wraps the Mersenne Twister generator
  9.   with a public interface that supports three common
  10.   pseudorandom number requests:
  11.   === Uniform deviate [0,1) ===
  12.   Random rnd(seed);
  13.   double r = rnd.uniform();
  14.   === Uniform deviate [0,hi) ===
  15.   Random rnd(seed);
  16.   unsigned long r = rnd.uniform(hi);
  17.   === Uniform deviate [lo,hi) ===
  18.   Random rnd(seed);
  19.   unsigned long r = rnd.uniform(lo, hi);
  20.   seed, lo, and hi are user supplied values, with
  21.   seed having a default setting of 1 for debugging
  22.   and testing purposes.
  23. */
  24. class Random {
  25.   // Arbitrary constants that work well
  26.   static const int           N = 624;
  27.   static const int           M = 397;
  28.   static const unsigned long MATRIX_A = 0x9908b0dfUL;
  29.   static const unsigned long UPPER_MASK = 0x80000000UL;
  30.   static const unsigned long LOWER_MASK = 0x7fffffffUL;
  31.   static const unsigned long MAX = 0xffffffffUL;
  32.  
  33.   unsigned long x[N]; // Random number pool
  34.   int           next; // Current pool index
  35. public:
  36.   Random(unsigned long seed = 1) { seedgen(seed); }
  37.  
  38.   // Return a uniform deviate in the range [0,1)
  39.   double uniform();
  40.   // Return a uniform deviate in the range [0,hi)
  41.   unsigned uniform(unsigned hi);
  42.   // Return a uniform deviate in the range [lo,hi)
  43.   unsigned uniform(unsigned lo, unsigned hi);
  44. private:
  45.   void seedgen(unsigned long seed);
  46.   unsigned long randgen();
  47. };
  48.  
  49. double Random::uniform()
  50. {
  51.   return randgen() * (1.0 / (MAX + 1.0));
  52. }
  53.  
  54. unsigned Random::uniform(unsigned hi)
  55. {
  56.   return static_cast<unsigned>(uniform() * hi);
  57. }
  58.  
  59. unsigned Random::uniform(unsigned lo, unsigned hi)
  60. {
  61.   return lo + uniform(hi - lo);
  62. }
  63.  
  64. void Random::seedgen(unsigned long seed)
  65. {
  66.   x[0] = seed & MAX;
  67.  
  68.   for (int i = 1; i < N; i++) {
  69.     x[i] = (1812433253UL * (x[i - 1] ^ (x[i - 1] >> 30)) + i);
  70.     x[i] &= MAX;
  71.   }
  72. }
  73.  
  74. // Mersenne Twister algorithm
  75. unsigned long Random::randgen()
  76. {
  77.   unsigned long rnd;
  78.  
  79.   // Refill the pool when exhausted
  80.   if (next == N) {
  81.     int a;
  82.  
  83.     for (int i = 0; i < N - 1; i++) {
  84.       rnd = (x[i] & UPPER_MASK) | x[i + 1] & LOWER_MASK;
  85.       a = (rnd & 0x1UL) ? MATRIX_A : 0x0UL;
  86.       x[i] = x[(i + M) % N] ^ (rnd >> 1) ^ a;
  87.     }
  88.  
  89.     rnd = (x[N - 1] & UPPER_MASK) | x[0] & LOWER_MASK;
  90.     a = (rnd & 0x1UL) ? MATRIX_A : 0x0UL;
  91.     x[N - 1] = x[M - 1] ^ (rnd >> 1) ^ a;
  92.  
  93.     next = 0; // Rewind index
  94.   }
  95.  
  96.   rnd = x[next++]; // Grab the next number
  97.  
  98.   // Voodoo to improve distribution
  99.   rnd ^= (rnd >> 11);
  100.   rnd ^= (rnd << 7) & 0x9d2c5680UL;
  101.   rnd ^= (rnd << 15) & 0xefc60000UL;
  102.   rnd ^= (rnd >> 18);
  103.  
  104.   return rnd;
  105. }

Copy & Paste


Comments


jjhaag 2007-11-03 03:18:23

A great, fast generator - but keep in mind it's not suitable for cryptography, since a fairly low (

f1sh 2007-11-08 09:53:20

Awsome, thanks a lot!


Add comment


You must be registered and logged on to </dream.in.code> to leave comments.




Be Social

Dream.In.Code RSS Feed Dream.In.Code LinkedIn Group Follow Us On Twitter

Live C++ Help!

C++ Tutorials

Reference Sheets

C++ Snippets

DIC Chatroom

Bye Bye Ads

Monthly Drawing

Thumb Drive

Top Contributors

Top 10 Kudos This Month