// maximum number provided by "NextNumber()" method
#define MY_MAX32_PSEUDONUMBER 2147483645UL
class CRandom32
{
private:
long int m_liModulus;
long int m_liMultiplier;
long int m_liRandomNumber;
long int AutoSeed();
public:
// constructors
CRandom32(){
m_liModulus = 2147483647; // 2^31 - 1
m_liMultiplier = 16807; // 7^5
m_liRandomNumber = AutoSeed();
}
CRandom32(long int seed){
m_liModulus = 2147483647;
m_liMultiplier = 16807;
m_liRandomNumber = seed;
}
// returns the next number of the sequence
long int NextNumber();
// returns a random value in the range [0, max]
long int NextLimitedNumber(long int max);
// returns a decimal number in the range [0, 1]
double NextDecimal();
// returns a pseudo-random bit (0 or 1).
short int NextBit();
};
long int CRandom32::NextNumber(){
__int64 temp = (__int64) m_liRandomNumber * m_liMultiplier;
// the two instructions below allow us to obtain
// a very good pseudo-random number generation for number
// in the range (1 - 2^31-1) and, in order to have a sequence
// starting from 0, I will move the sequence in the range
// (0 - 2^31-2) subtracting 1 to the number obtained
temp = temp % m_liModulus;
m_liRandomNumber = (long int) temp; // random number range is [1,MY_MAX32_PSEUDONUMBER+1]
return (m_liRandomNumber-1); // in order to have the range set to [0, MY_MAX32_PSEUDONUMBER]
}
long int CRandom32::NextLimitedNumber(long int max){
double temp = NextDecimal() * (max+1);
// I approximate with the minimum integer value
long int m_liRandomNumber = (long int) floor(temp);
// I know that the following is not so good to see, but when max<<MY_MAX32_PSEUDONUMBER
// the limited sequence still have quite good random properties.
if (m_liRandomNumber == (max+1))
m_liRandomNumber--;
return m_liRandomNumber;
}
double CRandom32::NextDecimal(){
double temp = (double) NextNumber() / (MY_MAX32_PSEUDONUMBER);
return temp;
}
short int CRandom32::NextBit(){
if (NextDecimal() > 0.5)
return 1;
else
return 0;
}
long int CRandom32::AutoSeed(){
unsigned __int64 temp = time(0) * clock();
long int seed = (long int) (temp % (MY_MAX32_PSEUDONUMBER+1));
seed++; // range of seed is now [1, MY_MAX32_PSEUDONUMBER+1], that is what I need
return seed;
}