// Copyright 1999 // College of Computer Science // Northeastern University Boston MA 02115 // This software may be used for educational purposes as long as this copyright // notice is retained at the top of all files // Should this software be modified, the words "Modified from Original" must be // included as a comment below this notice // All publication rights are retained. This software or its documentation may // not be published in any media either in whole or in part. /////////////////////////////////////////////////////////////////////////////// // Random.cpp /////////////////////////////////////////////////////////////////////////////// #include "CoreTools.h" // needed for core tools compile in Win32 #include "Random.h" long TheRandomSeed = 1; // seed // constants needed in NextRandom const long m = 16807; // seed multiplier const long q = maximum_long / m; // quotient: 2147483647 / 16807 = 127773 const long r = maximum_long % m; // remainder: 2147483647 % 16807 = 2836 // constant needed in NextDouble const double ML = double(maximum_long); void SetRandomSeed(long seed) { if (MinRandom <= seed && seed <= MaxRandom) TheRandomSeed = seed; else { unsigned long when = clock(); // get clock time if (when == 0) when = 1; // fix error while (when > MaxRandom) // force in range when -= MaxRandom; TheRandomSeed = when; // choose as seed } } long NextRandom() { long hi = TheRandomSeed / q; long lo = TheRandomSeed % q; long test = m * lo - r * hi; if (test > 0) TheRandomSeed = test; else TheRandomSeed = test + maximum_long; return TheRandomSeed; } double RandomDouble(double a, double b) { long n = NextRandom(); // n is the next random long double p = double(n) / ML; // ratio p satisfies 0 < p < 1 return (a + (b - a) * p); // linear interpolation from a to b } long RandomLong(long a, long b) { long n = NextRandom(); // n is the next random long if (a > b) { // force a <= b long c = a; a = b; b = c; } if (a <= 0) { // force b-a <= MaxRandom long c = a + MaxRandom; if (b > c) b = c; } long d = b - a + 1; // d = number of values from a to b return a + n % d; // note: a <= a + n % d <= b } void RandomNumber::SetRandomSeed(long seed) { if (MinRandom <= seed && seed <= MaxRandom) TheRandomSeed = seed; else { unsigned long when = clock(); // get clock time if (when == 0) when = 1; // fix error while (when > MaxRandom) // force in range when -= MaxRandom; TheRandomSeed = when; // choose as seed } } long RandomNumber::NextRandom() { long hi = TheRandomSeed / q; long lo = TheRandomSeed % q; long test = m * lo - r * hi; if (test > 0) TheRandomSeed = test; else TheRandomSeed = test + maximum_long; return TheRandomSeed; } double RandomNumber::RandomDouble(double a, double b) { long n = NextRandom(); // n is the next random long double p = double(n) / ML; // ratio p satisfies 0 < p < 1 return (a + (b - a) * p); // linear interpolation from a to b } long RandomNumber::RandomLong(long a, long b) { long n = NextRandom(); // n is the next random long if (a > b) { // force a <= b long c = a; a = b; b = c; } if (a <= 0) { // force b-a <= MaxRandom long c = a + MaxRandom; if (b > c) b = c; } long d = b - a + 1; // d = number of values from a to b return a + n % d; // note: a <= a + n % d <= b }