1 /*************************** RANDOMC.H ***************** 2007-09-22 Agner Fog *
\r
3 * This file contains class declarations and other definitions for the C++
\r
4 * library of uniform random number generators.
\r
6 * Overview of classes:
\r
7 * ====================
\r
9 * class CRandomMersenne:
\r
10 * Random number generator of type Mersenne twister.
\r
11 * Source file mersenne.cpp
\r
13 * class CRandomMother:
\r
14 * Random number generator of type Mother-of-All (Multiply with carry).
\r
15 * Source file mother.cpp
\r
18 * Member functions (methods):
\r
19 * ===========================
\r
21 * All these classes have identical member functions:
\r
23 * Constructor(uint32 seed):
\r
24 * The seed can be any integer. Usually the time is used as seed.
\r
25 * Executing a program twice with the same seed will give the same sequence of
\r
26 * random numbers. A different seed will give a different sequence.
\r
28 * void RandomInit(uint32 seed);
\r
29 * Re-initializes the random number generator with a new seed.
\r
31 * void RandomInitByArray(uint32 seeds[], int length);
\r
32 * In CRandomMersenne only: Use this function if you want to initialize with
\r
33 * a seed with more than 32 bits. All bits in the seeds[] array will influence
\r
34 * the sequence of random numbers generated. length is the number of entries
\r
35 * in the seeds[] array.
\r
38 * Gives a floating point random number in the interval 0 <= x < 1.
\r
39 * The resolution is 32 bits in CRandomMother and CRandomMersenne.
\r
41 * int IRandom(int min, int max);
\r
42 * Gives an integer random number in the interval min <= x <= max.
\r
43 * (max-min < MAXINT).
\r
44 * The precision is 2^-32 (defined as the difference in frequency between
\r
45 * possible output values). The frequencies are exact if max-min+1 is a
\r
48 * int IRandomX(int min, int max);
\r
49 * Same as IRandom, but exact. In CRandomMersenne only.
\r
50 * The frequencies of all output values are exactly the same for an
\r
51 * infinitely long sequence. (Only relevant for extremely long sequences).
\r
54 * Gives 32 random bits.
\r
59 * The file EX-RAN.CPP contains an example of how to generate random numbers.
\r
62 * Optimized version:
\r
63 * ==================
\r
64 * Faster versions of these random number generators are provided as function
\r
65 * libraries in asmlib.zip. These function libraries are coded in assembly
\r
66 * language and support only x86 platforms, including 32-bit and 64-bit
\r
67 * Windows, Linux, BSD, Mac OS-X (Intel based). Use asmlibran.h from asmlib.zip
\r
70 * Non-uniform random number generators:
\r
71 * =====================================
\r
72 * Random number generators with various non-uniform distributions are available
\r
73 * in stocc.zip (www.agner.org/random).
\r
76 * Further documentation:
\r
77 * ======================
\r
78 * The file randomc.htm contains further documentation on these random number
\r
84 * © 1997 - 2007 Agner Fog. All software in this library is published under the
\r
85 * GNU General Public License with the further restriction that it cannot be
\r
86 * used for gambling applications. See licence.htm
\r
87 *******************************************************************************/
\r
93 // Define 32 bit signed and unsigned integers.
\r
94 // Change these definitions, if necessary, to match a particular platform
\r
95 #if defined(_WIN16) || defined(__MSDOS__) || defined(_MSDOS)
\r
96 // 16 bit systems use long int for 32 bit integer
\r
97 typedef long int int32; // 32 bit signed integer
\r
98 typedef unsigned long int uint32; // 32 bit unsigned integer
\r
100 // Most other systems use int for 32 bit integer
\r
101 typedef int int32; // 32 bit signed integer
\r
102 typedef unsigned int uint32; // 32 bit unsigned integer
\r
105 // Define 64 bit signed and unsigned integers, if possible
\r
106 #if (defined(__WINDOWS__) || defined(_WIN32)) && (defined(_MSC_VER) || defined(__INTEL_COMPILER))
\r
107 // Microsoft and other compilers under Windows use __int64
\r
108 typedef __int64 int64; // 64 bit signed integer
\r
109 typedef unsigned __int64 uint64; // 64 bit unsigned integer
\r
110 #define INT64_DEFINED // Remember that int64 is defined
\r
111 #elif defined(__unix__) && (defined(_M_IX86) || defined(_M_X64))
\r
112 // Gnu and other compilers under Linux etc. use long long
\r
113 typedef long long int64; // 64 bit signed integer
\r
114 typedef unsigned long long uint64; // 64 bit unsigned integer
\r
115 #define INT64_DEFINED // Remember that int64 is defined
\r
117 // 64 bit integers not defined
\r
118 // You may include definitions for other platforms here
\r
122 /***********************************************************************
\r
123 System-specific user interface functions
\r
124 ***********************************************************************/
\r
126 void EndOfProgram(void); // System-specific exit code (userintf.cpp)
\r
128 void FatalError(char * ErrorText); // System-specific error reporting (userintf.cpp)
\r
131 /***********************************************************************
\r
132 Define random number generator classes
\r
133 ***********************************************************************/
\r
135 class CRandomMersenne { // Encapsulate random number generator
\r
137 // Define constants for type MT11213A:
\r
145 #define MERS_A 0xE4BD75F5
\r
146 #define MERS_B 0x655E5280
\r
147 #define MERS_C 0xFFD58000
\r
149 // or constants for type MT19937:
\r
157 #define MERS_A 0x9908B0DF
\r
158 #define MERS_B 0x9D2C5680
\r
159 #define MERS_C 0xEFC60000
\r
162 CRandomMersenne(uint32 seed) { // Constructor
\r
163 RandomInit(seed); LastInterval = 0;}
\r
164 void RandomInit(uint32 seed); // Re-seed
\r
165 void RandomInitByArray(uint32 seeds[], int length); // Seed by more than 32 bits
\r
166 int IRandom (int min, int max); // Output random integer
\r
167 int IRandomX(int min, int max); // Output random integer, exact
\r
168 double Random(); // Output random float
\r
169 uint32 BRandom(); // Output random bits
\r
171 void Init0(uint32 seed); // Basic initialization procedure
\r
172 uint32 mt[MERS_N]; // State vector
\r
173 int mti; // Index into mt
\r
174 uint32 LastInterval; // Last interval length for IRandomX
\r
175 uint32 RLimit; // Rejection limit used by IRandomX
\r
176 enum TArch {LITTLE_ENDIAN1, BIG_ENDIAN1, NONIEEE}; // Definition of architecture
\r
177 TArch Architecture; // Conversion to float depends on architecture
\r
181 class CRandomMother { // Encapsulate random number generator
\r
183 void RandomInit(uint32 seed); // Initialization
\r
184 int IRandom(int min, int max); // Get integer random number in desired interval
\r
185 double Random(); // Get floating point random number
\r
186 uint32 BRandom(); // Output random bits
\r
187 CRandomMother(uint32 seed) { // Constructor
\r
190 uint32 x[5]; // History buffer
\r