I don't know exactly why you cannot use rand
itself but, if not, then you could just roll your own. Use your integer to seed a number then use the standard Xn+1 = a * Xn + c mod m
.
The Wikipedia page for linear congruential method has some sample values for a
, c
and m
.
Now LCM isn't the greatest random number generator in the world but, if you just want numbers that "look somewhat randomised", it should be sufficient.
As an example of an LCM algorithm, the following function, based on the Microsoft Visual/Quick C/C++
entry from that linked page above:
// LCM pseudo-random number generator.
// Outputs numbers from 0..32767 inclusive.
// With protection against identical sequences.
// due to full 32-bit cycle but only returning 15 bits.
uint32_t myRand (void) {
const static uint32_t a = 214013U;
const static uint32_t c = 2531011U;
// m is, of course, 2^32 since the values will wrap.
static uint32_t seed = 1;
seed = seed * a + c;
return (seed >> 16) & 0x7FFF;
}
has a cycle time of the full range of 32-bit numbers but only returns certain bits of the seed each time, which reduces the appearance of identical sequences.
If you want a C++ class to do this so that all random number generators are independent of each other (as suggested by TomZ), you can use something like:
class myRand {
public:
myRand ();
myRand (unsigned int newSeed);
~myRand ();
void setSeed (unsigned int newSeed);
unsigned int getSeed (void);
unsigned int next (void);
private:
unsigned int seed;
const static unsigned int a = 214013U;
const static unsigned int c = 2531011U;
};
myRand::myRand () { seed = 1; }
myRand::myRand (unsigned int newSeed) { setSeed (newSeed); }
myRand::~myRand () { }
void myRand::setSeed (unsigned int newSeed) { seed = newSeed; }
unsigned int myRand::getSeed (void) { return seed; }
unsigned int myRand::next (void) {
seed = (seed * a + c) & 0xffffffff;
return (seed >> 16) & 0x7fff;
}
#include <iostream>
int main (void) {
myRand r (5);
std::cout << r.next() << "\n"; // 54
std::cout << r.next() << "\n"; // 28693
unsigned int saveSeed = r.getSeed();
std::cout << r.next() << "\n"; // 12255
std::cout << r.next() << "\n"; // 24449
r.setSeed (saveSeed);
std::cout << r.next() << "\n"; // 12255
std::cout << r.next() << "\n"; // 24449
return 0;
}