3 // Copyright (C) 1999 Allen Akin All Rights Reserved.
5 // Permission is hereby granted, free of charge, to any person
6 // obtaining a copy of this software and associated documentation
7 // files (the "Software"), to deal in the Software without
8 // restriction, including without limitation the rights to use,
9 // copy, modify, merge, publish, distribute, sublicense, and/or
10 // sell copies of the Software, and to permit persons to whom the
11 // Software is furnished to do so, subject to the following
14 // The above copyright notice and this permission notice shall be
15 // included in all copies or substantial portions of the
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
19 // KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
20 // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
21 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ALLEN AKIN BE
22 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 // AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
24 // OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 // DEALINGS IN THE SOFTWARE.
32 // rand.h: Simple random sequence generation utilities.
34 // We provide these to eliminate dependencies on the operating
35 // system's random number generator. This makes it possible to
36 // compare results for a given graphics device running under different
39 // Based on Numerical Recipes, 2d ed., p. 284.
48 ///////////////////////////////////////////////////////////////////////////////
49 // RandomBase: Quick-and-dirty linear congruential generator that serves as
50 // a base for other random-sequence classes.
51 ///////////////////////////////////////////////////////////////////////////////
55 inline RandomBase(unsigned int seed
): i(seed
) { }
56 inline RandomBase(): i(1) { }
57 inline unsigned int next() {
58 i
= 1664525 * i
+ 1013904223;
61 }; // class RandomBase
63 ///////////////////////////////////////////////////////////////////////////////
64 // RandomBits: Returns a given number of random bits (expressed as an unsigned
65 // int, so the maximum portable number of bits is 32).
66 ///////////////////////////////////////////////////////////////////////////////
67 class RandomBits
: public RandomBase
{
70 inline RandomBits(unsigned int bits
, unsigned int seed
):
71 RandomBase(seed
), shift(32 - bits
) { }
72 inline RandomBits(unsigned int bits
):
73 RandomBase(), shift(32 - bits
) { }
74 inline unsigned int next() { return RandomBase::next() >> shift
; }
75 }; // class RandomBits
77 ///////////////////////////////////////////////////////////////////////////////
78 // RandomSignedBits: Returns a given number of random bits (expressed as a
79 // signed int, so the maximum portable number of bits is 32 including sign).
80 ///////////////////////////////////////////////////////////////////////////////
81 class RandomSignedBits
: public RandomBase
{
84 inline RandomSignedBits(unsigned int bits
, unsigned int seed
):
85 RandomBase(seed
), shift(32 - bits
) { }
86 inline RandomSignedBits(unsigned int bits
):
87 RandomBase(), shift(32 - bits
) { }
89 return static_cast<int>(RandomBase::next()) >> shift
;
91 }; // class RandomSignedBits
93 ///////////////////////////////////////////////////////////////////////////////
94 // RandomDouble: Returns a random floating-point value in the closed
95 // interval [0.0, 1.0].
96 ///////////////////////////////////////////////////////////////////////////////
97 class RandomDouble
: public RandomBase
{
99 inline RandomDouble(unsigned int seed
): RandomBase(seed
) { }
100 inline RandomDouble(): RandomBase() { }
101 inline double next() {
102 return static_cast<double>(RandomBase::next()) / 4294967295.0;
104 }; // class RandomDouble
106 ///////////////////////////////////////////////////////////////////////////////
107 // RandomBitsDouble: Returns a random floating-point value in the closed
108 // interval [0.0, 1.0], but with possible values limited by a generator
109 // returning a specific number of bits.
110 ///////////////////////////////////////////////////////////////////////////////
111 class RandomBitsDouble
: public RandomBits
{
114 inline RandomBitsDouble(unsigned int bits
, unsigned int seed
):
115 RandomBits(bits
, seed
) { scale
= (1 << bits
) - 1.0; }
116 inline RandomBitsDouble(unsigned int bits
):
117 RandomBits(bits
) { scale
= (1 << bits
) - 1.0; }
118 inline double next() {
119 return static_cast<double>(RandomBits::next()) / scale
;
121 }; // class RandomBitsDouble