Hgeocities.com/madaboutcha/RandomNumberGeneration.htmgeocities.com/madaboutcha/RandomNumberGeneration.htmdelayedxiJ)2 OKtext/htmlpN
//------------------------------------------------------------------------
// Copyright (C) Sewell Development Corporation, 1994 - 1998.
//     Web: www.sewelld.com      E-mail: support@sewelld.com
//
// LICENSE: Paid-up licensees are authorized to use this code on a site-wide
// basis and incorporate it into their software products, provided that the
// code is not resold as stand-alone source code or as part of a code library,
// and that this copyright notice and license agreement are not removed.
//------------------------------------------------------------------------

//  Interface definition for random number classes.

#pragma once

//------------------------- RandomNumber ---------------------------------

// Returns pseudo-random numbers of various types from an underlying
// sequence of pseudo-random 64-bit numbers produced with a linear
// congruential generator.  No more than 32-bits of data are taken from
// the sequence at each step.  Therefore calls that return more than 32-bits
// of random data (i.e. the 64-bit integer return types and the double type),
// use two iterations of the underlying sequence to produce the data.

// All linear congruential generators suffer from certain statistical
// weaknesses when used for applications demanding highly random data.
// To mitigate that problem, a derived ShuffledRandomNumber class is
// provided.  This overrides the GetUint32() function, which is used by all
// the other functions to get the next 32 bits of random data.  The 
// RandomNumber::GetUnit32() function simply returns the high order 32-bits of 
// the next 64-bit value from the generator.  The ShuffledRandomNumber::GetUint32()
// function takes a 32-bit CRC (cyclic redundancy check) of all 64-bits from
// the next generator value.  This greatly improves the quality of the returned 
// random data for statistical work - at the cost of some extra computational time.
// If your application is not demanding of this higher statistical quality, 
// and you want to improve execution speed, use the RandomNumber class instead of
// the ShuffledRandomNumber class.

// A 64-bit "seed" value is passed to the constructor to supply the starting
// point in the pseudo-random 64-bit sequence.  The second optional argument is
// a "prime addend" for the generator sequence, which should be a large 64-bit
// prime number.  If you omit this argument, or pass a zero, a standard prime
// addend is supplied.  You would typically only need to supply this argument
// if you want to generate multiple reproducible streams of random numbers
// (possibly in different threads) and you want to make sure that the streams
// are relatively independent.  The NextLargePrimeAddend() routine is provided
// to help you generate unique large prime addends, or you can roll your own.
// The prime numbers generated by this call are not sequential.  They are
// essentially randomly distributed (in a reproducible way) throughout the
// number space above 0x4000000000000000 (larger prime numbers generate streams
// that show less correlation with each other).  See the header file 
// "PrimeTest.h" for more information on how this routine tests for primality.

// You can always reproduce a given pseudo-random sequence by passing the same starting 
// seed value and prime addend to the constructor as was originally passsed.  You can also 
// save the state of a sequence with SaveState(), or restore it later with 
// RestoreState().

// If you want to start at a random point in the sequence, call the
// RandomNumberSeed() function and pass its return value to the constructor
// of RandomNumber().  RandomNumberSeed() can also be used as a general
// purpose way of coming up with a fairly random 64-bit number.  It
// generates this value by taking a 64-bit CRC (cyclic redundancy check)
// of all of the following data:
//		1)  The 64-bit value returned by Win32 GetSystemTimeAsFileTime().
//		2)	The 32-bit value returned by Win32 GetTickCount().
//		3)	The 64-bit value returned by Win32 QueryPerformanceCounter
//			(if a high performance counter is available in the system).
//		4)	The 64-bit cpu cycle count returned by QueryCpuCycleCounter()
//			(if running on a Pentium compatible system).

unsigned __int64 RandomNumberSeed();

// Generate another large 64-bit prime number for use as a prime addend.
// This routine chews up several milliseconds of CPU time, so use it only
// when you need to (typically when multiple streams of random data are
// desired).  When different prime addends are passed to different
// RandomNumber objects, the random sequences produced are different and
// essentially uncorrelated, even if the same seed is passed.  We
// haven't calculated how many prime numbers this routine produces before
// it repeats - but it is many billion.  
unsigned __int64 NextLargePrimeAddend(int numRabinMillerIterations = 1);

class RandomNumber {
public:
	RandomNumber(unsigned __int64 seed, unsigned __int64 primeAddend = 0);
	void SaveState(unsigned __int64* seed, unsigned __int64* primeAddend);
	void RestoreState(unsigned __int64 seed, unsigned __int64 primeAddend);

	// Return a random 32-bit unsigned integer
	virtual unsigned __int32 GetUint32();

	// Return a random 32-bit unsigned integer between specified minimum and maximum (inclusive).
	unsigned __int32 GetUint32InRange(unsigned __int32 minimum, unsigned __int32 maximum);

	// Return a random 32-bit signed integer
	__int32 GetInt32() { 
		return (__int32) GetUint32(); 
	}

	// Return a random 32-bit integer between specified minimum and maximum (inclusive).
	__int32 GetInt32InRange(__int32 minimum, __int32 maximum) {
		return (__int32) GetUint32InRange( (unsigned __int32) minimum, (unsigned __int32) maximum);
	}

	// Return a random 64-bit unsigned integer
	unsigned __int64 GetUint64();

	// Return a random 64-bit signed integer
	__int64 GetInt64() {
		return (__int64) GetUint64();
	}

	// Return a random float anywhere in the valid range.
	float GetFloat();

	// Return a random float between the specified minimum and maximum (NOT inclusive).
	float GetFloatInRange(float minimum, float maximum);

	// Return a random double anywhere in the valid range.
	double GetDouble();

	// Return a random double between the specified minimum and maximum (NOT inclusive).
	double GetDoubleInRange(double minimum, double maximum);

protected:
	unsigned __int64 m_seed;
	unsigned __int64 m_primeAddend;
};

// This class is identical in purpose to RandomNumber.  The only difference is that
// bits from the linear congruential generator are shuffled using a CRC before they
// are returned.  Which one to use is simply a tradeoff between slower execution
// times with this class versus better statistical quality of the returned bits.
class ShuffledRandomNumber : public RandomNumber {
public:
	ShuffledRandomNumber(unsigned __int64 seed, unsigned __int64 primeAddend = 0)
		: RandomNumber(seed, primeAddend) { }

	// Return a random 32-bit unsigned integer
	virtual unsigned __int32 GetUint32();
};