Note: this information applies to RNG algorithms used through either a "Polymorphic" or a "LightWeight" interface. Those used through a "Raw" interface only suport a subset of the interface described here. ======================================================================== Using PractRand for pseudo-random number generation: ======================================================================== 1. You have installed and configured PractRand, right? See installing.txt 2. Pick an RNG algorithm. You can look at RNG_engines.txt for information about which ones would be best for you. Or if you don't want to do that, then just use hc256, the polymorphic version of it. That is: PractRand::RNGs::Polymorphic::hc256 3. Include the PractRand headers needed. If all you're using is an RNG from PractRand then all you need to include is PractRand.h and a header for the specific RNG algorithm that you wish to use: #include "PractRand.h" #include "PractRand/RNGs/hc256.h" If your program has multiple source files that need to be able to use the RNG then you may need to #include those in each source file, or inside one of your own headers. 4. Decide how you want to seed your RNG. Pseudo-random number generators need to be seeded. A typical RNG in PractRand can be seeded by any of several methods: Note: most seeding interfaces are not available on "raw" RNGs. See RNG_interface_variants.txt for details on raw RNGs. 4a. automatic seeding: Easy to use, attempts to make the RNG produce a different sequence on each run of your program. You give the RNGs constructor a parameter of PractRand::SEED_AUTO and it takes care of the rest. This is generally easy and effective. It should work for most multithreaded programs. It is not recommended for cryptographic usage though. If your RNG has already been constructed and you want to overrides its current state with an automatic seeding then call the autoseed() method. eg PractRand::RNGs::Polymorphic::hc256 rng(PractRand::SEED_AUTO); or rng.autoseed(); 4b. integer seeding: Typically used when you want to force the RNG to produce the same sequence of numbers of every run (perhaps for debugging purposes), or when you want your RNG seed to be a value that is easy to print out. If your RNG has already been constructed and you want to overrides its current state with an integer seeding then call the seed() method and pass it an integer. The integer type it expects is a 64 bit unsigned value. If you pass it the literal value "0" then it may get confused because 0 is also NULL, which could be a pointer of the type used for seeding in 4c below. Note that seeding from a single integer is NEVER sufficient for cryptographic usage. eg PractRand::RNGs::Polymorphic::hc256 rng(13); or rng.seed(13); 4c. seeding from another RNG: You can seed one RNG from a second RNG by passing the seeder to the seedees constructor or calling the seedees seed() method with a pointer at the seeder as its parameter. The RNG that is being used as a seed (aka the seeder) must be polymorphic. If the seeder RNG is not cryptographic then the seeding will not be cryptographically secure. eg PractRand::RNGs::Polymorphic::isaac32x256 seeder_rng(PractRand::SEED_AUTO); PractRand::RNGs::Polymorphic::isaac32x256 seedee_rng( &seeder_rng ); or seedee_rng.seed( &seeder_rng ); 4d. seeding later, after construction: Because failing to seed an RNG is generally a bug, PractRand insists that you give each RNGs constructor a parameter that acts as the seed. But if for some reason you want to leave an RNG unseeded then you can construct an RNG with the parameter PractRand::SEED_NONE. Requesting random numbers from such an RNG produces undefined results (depending upon which RNG is used it will likely either return not-very-random numbers or crash). However you can then seed it later using the seed() or autoseed() methods. Exception: Some RNGs have a default state. Those RNGs, if no seed is used, start out in their default state, which does have defined results when used. 4e. entropy pools: Certain special RNGs, called entropy pools, are intended for use in more specialized seeding scenarios. They support all the options that non-entropy-pooling RNGs support, but have additional functionality relating to seeding. See RNG_entropy_pools.txt for more information on them. 5. Declare an instance of your RNG. For single-threaded programs this is generally done as: PractRand::RNGs::Polymorphic::hc256 my_rng( my_seed ); For a multi-threaded program this is typically done as: __thread PractRand::RNGs::Polymorphic::hc256 my_rng( my_seed ); or like this: __declspec(thread) PractRand::RNGs::Polymorphic::hc256 my_rng( my_seed ); ...depending upon what compiler you are using. 6. Get random numbers from your RNG. You can see the full base class for polymorphic RNGs as PractRand::RNGs::vRNG in PractRand/rng_basics.h That class is also available under a number of other aliases: PractRand::RNGs::Polymorphic::vRNG PractRand::RNGs::PolymorphicRNG PractRand::RNGs::Polymorphic::PolymorphicRNG Every PractRand RNG that is not designated as "raw" includes support for all of the following methods: //integers packed full of random bits Uint8 raw8(); Uint16 raw16(); Uint32 raw32(); Uint64 raw64(); //uniform 32 bit integers Uint32 randi(Uint32 max);//uniform random number in [0..max) Uint32 randi(Uint32 min, Uint32 max);//uniform random number in [min..max) //uniform 32 bit integers, faster but biased //note: avoid using these two on low-end embedded CPUs - these use multiplication internally Uint32 randi_fast(Uint32 max);//uniform random number in [0..max), with bias Uint32 randi_fast(Uint32 min, Uint32 max);//uniform random number in [min..max), with bias //uniform 64 bit integers (long integer) Uint64 randli(Uint64 max);//uniform random number in [0..max) Uint64 randli(Uint64 min, Uint64 max);//uniform random number in [min..max) //uniform random floats float randf(); //uniform random number in [0..1) float randf(float max); //uniform random number in [0..max) float randf(float min, float max); //uniform random number in [min..max) //uniform random doubles (long floating point) double randlf(); //uniform random number in [0..1) double randlf(double max); //uniform random number in [0..max) double randlf(double min, double max); //uniform random number in [min..max) That covers all the basic uniform distributions. If you want a non-uniform distribution such as a gaussian distribution, then you will need another package. One option is Boost / C++0x TR1, which offers several distributions as template objects. PractRand RNGs are compatible with those distributions if the symbol PRACTRAND_BOOST_COMPATIBILITY is defined prior to the inclusion of PractRands headers.