00001 /*************************** RANDOMC.H ***************** 2007-09-22 Agner Fog * 00002 * 00003 * This file contains class declarations and other definitions for the C++ 00004 * library of uniform random number generators. 00005 * 00006 * Overview of classes: 00007 * ==================== 00008 * 00009 * class CRandomMersenne: 00010 * Random number generator of type Mersenne twister. 00011 * Source file mersenne.cpp 00012 * 00013 * class CRandomMother: 00014 * Random number generator of type Mother-of-All (Multiply with carry). 00015 * Source file mother.cpp 00016 * 00017 * 00018 * Member functions (methods): 00019 * =========================== 00020 * 00021 * All these classes have identical member functions: 00022 * 00023 * Constructor(uint32 seed): 00024 * The seed can be any integer. Usually the time is used as seed. 00025 * Executing a program twice with the same seed will give the same sequence of 00026 * random numbers. A different seed will give a different sequence. 00027 * 00028 * void RandomInit(uint32 seed); 00029 * Re-initializes the random number generator with a new seed. 00030 * 00031 * void RandomInitByArray(uint32 seeds[], int length); 00032 * In CRandomMersenne only: Use this function if you want to initialize with 00033 * a seed with more than 32 bits. All bits in the seeds[] array will influence 00034 * the sequence of random numbers generated. length is the number of entries 00035 * in the seeds[] array. 00036 * 00037 * double Random(); 00038 * Gives a floating point random number in the interval 0 <= x < 1. 00039 * The resolution is 32 bits in CRandomMother and CRandomMersenne. 00040 * 00041 * int IRandom(int min, int max); 00042 * Gives an integer random number in the interval min <= x <= max. 00043 * (max-min < MAXINT). 00044 * The precision is 2^-32 (defined as the difference in frequency between 00045 * possible output values). The frequencies are exact if max-min+1 is a 00046 * power of 2. 00047 * 00048 * int IRandomX(int min, int max); 00049 * Same as IRandom, but exact. In CRandomMersenne only. 00050 * The frequencies of all output values are exactly the same for an 00051 * infinitely long sequence. (Only relevant for extremely long sequences). 00052 * 00053 * uint32 BRandom(); 00054 * Gives 32 random bits. 00055 * 00056 * 00057 * Example: 00058 * ======== 00059 * The file EX-RAN.CPP contains an example of how to generate random numbers. 00060 * 00061 * 00062 * Optimized version: 00063 * ================== 00064 * Faster versions of these random number generators are provided as function 00065 * libraries in asmlib.zip. These function libraries are coded in assembly 00066 * language and support only x86 platforms, including 32-bit and 64-bit 00067 * Windows, Linux, BSD, Mac OS-X (Intel based). Use asmlibran.h from asmlib.zip 00068 * 00069 * 00070 * Non-uniform random number generators: 00071 * ===================================== 00072 * Random number generators with various non-uniform distributions are available 00073 * in stocc.zip (www.agner.org/random). 00074 * 00075 * 00076 * Further documentation: 00077 * ====================== 00078 * The file randomc.htm contains further documentation on these random number 00079 * generators. 00080 * 00081 * 00082 * Copyright: 00083 ============ 00084 * © 1997 - 2007 Agner Fog. All software in this library is published under the 00085 * GNU General Public License with the further restriction that it cannot be 00086 * used for gambling applications. See licence.htm 00087 *******************************************************************************/ 00088 00089 #ifndef RANDOMC_H 00090 #define RANDOMC_H 00091 00092 00093 // Define 32 bit signed and unsigned integers. 00094 // Change these definitions, if necessary, to match a particular platform 00095 #if defined(_WIN16) || defined(__MSDOS__) || defined(_MSDOS) 00096 // 16 bit systems use long int for 32 bit integer 00097 typedef long int int32; // 32 bit signed integer 00098 typedef unsigned long int uint32; // 32 bit unsigned integer 00099 #else 00100 // Most other systems use int for 32 bit integer 00101 typedef int int32; // 32 bit signed integer 00102 typedef unsigned int uint32; // 32 bit unsigned integer 00103 #endif 00104 00105 // Define 64 bit signed and unsigned integers, if possible 00106 #if (defined(__WINDOWS__) || defined(_WIN32)) && (defined(_MSC_VER) || defined(__INTEL_COMPILER)) 00107 // Microsoft and other compilers under Windows use __int64 00108 typedef __int64 int64; // 64 bit signed integer 00109 typedef unsigned __int64 uint64; // 64 bit unsigned integer 00110 #define INT64_DEFINED // Remember that int64 is defined 00111 #elif defined(__unix__) && (defined(_M_IX86) || defined(_M_X64)) 00112 // Gnu and other compilers under Linux etc. use long long 00113 typedef long long int64; // 64 bit signed integer 00114 typedef unsigned long long uint64; // 64 bit unsigned integer 00115 #define INT64_DEFINED // Remember that int64 is defined 00116 #else 00117 // 64 bit integers not defined 00118 // You may include definitions for other platforms here 00119 #endif 00120 00121 00122 /*********************************************************************** 00123 System-specific user interface functions 00124 ***********************************************************************/ 00125 00126 void EndOfProgram(void); // System-specific exit code (userintf.cpp) 00127 00128 void FatalError(char * ErrorText); // System-specific error reporting (userintf.cpp) 00129 00130 00131 /*********************************************************************** 00132 Define random number generator classes 00133 ***********************************************************************/ 00134 00135 class CRandomMersenne { // Encapsulate random number generator 00136 #if 0 00137 // Define constants for type MT11213A: 00138 #define MERS_N 351 00139 #define MERS_M 175 00140 #define MERS_R 19 00141 #define MERS_U 11 00142 #define MERS_S 7 00143 #define MERS_T 15 00144 #define MERS_L 17 00145 #define MERS_A 0xE4BD75F5 00146 #define MERS_B 0x655E5280 00147 #define MERS_C 0xFFD58000 00148 #else 00149 // or constants for type MT19937: 00150 #define MERS_N 624 00151 #define MERS_M 397 00152 #define MERS_R 31 00153 #define MERS_U 11 00154 #define MERS_S 7 00155 #define MERS_T 15 00156 #define MERS_L 18 00157 #define MERS_A 0x9908B0DF 00158 #define MERS_B 0x9D2C5680 00159 #define MERS_C 0xEFC60000 00160 #endif 00161 public: 00162 CRandomMersenne(uint32 seed) { // Constructor 00163 RandomInit(seed); LastInterval = 0;} 00164 void RandomInit(uint32 seed); // Re-seed 00165 void RandomInitByArray(uint32 seeds[], int length); // Seed by more than 32 bits 00166 int IRandom (int min, int max); // Output random integer 00167 int IRandomX(int min, int max); // Output random integer, exact 00168 double Random(); // Output random float 00169 uint32 BRandom(); // Output random bits 00170 private: 00171 void Init0(uint32 seed); // Basic initialization procedure 00172 uint32 mt[MERS_N]; // State vector 00173 int mti; // Index into mt 00174 uint32 LastInterval; // Last interval length for IRandomX 00175 uint32 RLimit; // Rejection limit used by IRandomX 00176 enum TArch {LITTLE_ENDIAN1, BIG_ENDIAN1, NONIEEE}; // Definition of architecture 00177 TArch Architecture; // Conversion to float depends on architecture 00178 }; 00179 00180 00181 class CRandomMother { // Encapsulate random number generator 00182 public: 00183 void RandomInit(uint32 seed); // Initialization 00184 int IRandom(int min, int max); // Get integer random number in desired interval 00185 double Random(); // Get floating point random number 00186 uint32 BRandom(); // Output random bits 00187 CRandomMother(uint32 seed) { // Constructor 00188 RandomInit(seed);} 00189 protected: 00190 uint32 x[5]; // History buffer 00191 }; 00192 00193 #endif