BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bdlb_random.h
Go to the documentation of this file.
1/// @file bdlb_random.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bdlb_random.h -*-C++-*-
8#ifndef INCLUDED_BDLB_RANDOM
9#define INCLUDED_BDLB_RANDOM
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bdlb_random bdlb_random
15/// @brief Provide a suite of procedures for random-number generation.
16/// @addtogroup bdl
17/// @{
18/// @addtogroup bdlb
19/// @{
20/// @addtogroup bdlb_random
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bdlb_random-purpose"> Purpose</a>
25/// * <a href="#bdlb_random-classes"> Classes </a>
26/// * <a href="#bdlb_random-description"> Description </a>
27/// * <a href="#bdlb_random-usage"> Usage </a>
28/// * <a href="#bdlb_random-example-1-simulating-a-pair-of-dice"> Example 1: Simulating a Pair of Dice </a>
29///
30/// # Purpose {#bdlb_random-purpose}
31/// Provide a suite of procedures for random-number generation.
32///
33/// # Classes {#bdlb_random-classes}
34///
35/// - bdlb::Random: namespace for a suite of random-number generation procedures
36///
37/// @see bdlb_pcgrandomgenerator
38///
39/// # Description {#bdlb_random-description}
40/// This component provides a utility `struct`, `bdlb::Random`,
41/// that is a namespace for a suite of functions used to efficiently generate
42/// random numbers over a specific range of values. The seed (or current state)
43/// is maintained externally. Two variants of a 15-bit random number generator
44/// are provided: one has a single [in/out] seed parameter, which is first used
45/// then updated; the other takes the current seed as an [input] parameter, and
46/// stores a new seed in an [output] parameter. A third generator produces
47/// 32-bit random numbers employing the PCG algorithm.
48///
49/// ## Usage {#bdlb_random-usage}
50///
51///
52/// This section illustrates intended use of this component.
53///
54/// ### Example 1: Simulating a Pair of Dice {#bdlb_random-example-1-simulating-a-pair-of-dice}
55///
56///
57/// This example shows how one might use `bdlb::Random` to create and use a
58/// class to simulate the roll of a single die in a game, such as craps, that
59/// uses dice.
60///
61/// First, we define the `Die` class itself:
62/// @code
63/// // =========
64/// // class Die
65/// // =========
66///
67/// class Die {
68///
69/// // DATA
70/// int d_seed; // current state, used to generate next role of this die
71///
72/// public:
73/// // CREATORS
74///
75/// /// Create an object used to simulate a single die, using the
76/// /// specified `initialSeed`.
77/// Die(int initialSeed);
78///
79/// // MANIPULATORS
80///
81/// /// Return the next pseudo-random value in the range `[1 .. 6]`,
82/// /// based on the sequence of values established by the initial seed
83/// /// value supplied at construction.
84/// int roll();
85/// };
86///
87/// // ---------
88/// // class Die
89/// // ---------
90///
91/// // CREATORS
92/// inline
93/// Die::Die(int initialSeed)
94/// : d_seed(initialSeed)
95/// {
96/// }
97///
98/// // MANIPULATORS
99/// int Die::roll()
100/// {
101/// int result;
102///
103/// do {
104/// result = bdlb::Random::generate15(&d_seed) & 7;
105/// } while (result > 5);
106///
107/// return result + 1;
108/// }
109/// @endcode
110/// Now, we can use our `Dice` class to get the random numbers needed to
111/// simulate a game of craps. Note that the game of craps requires two dice.
112///
113/// We can instantiate a single `Die` and role it twice,
114/// @code
115/// void rollOneDieTwice()
116/// {
117/// Die a(123);
118///
119/// int d1 = a.roll();
120/// int d2 = a.roll();
121///
122/// cout << "d1 = " << d1 << ", d2 = " << d2 << endl; // d1 = 3, d2 = 5
123/// }
124/// @endcode
125/// Alternatively, we could create two instances of `Die`, with separate initial
126/// seeds, and role each one once:
127/// @code
128/// void rollTwoDice()
129/// {
130/// Die a(123);
131/// Die b(456);
132///
133/// int d1 = a.roll();
134/// int d2 = b.roll();
135///
136/// cout << "d1 = " << d1 << ", d2 = " << d2 << endl; // d1 = 3, d2 = 1
137/// }
138/// @endcode
139/// Note that the specification of separate seeds is important to produce a
140/// proper distribution for our game. If we had shared the seed value each die
141/// would always produce the same sequence of values as the other.
142/// @code
143/// void shareSeed()
144/// {
145/// Die a(123); // BAD IDEA
146/// Die b(123); // BAD IDEA
147///
148/// int d1 = a.roll();
149/// int d2 = b.roll();
150/// assert(d2 == d1);
151///
152/// }
153/// @endcode
154/// @}
155/** @} */
156/** @} */
157
158/** @addtogroup bdl
159 * @{
160 */
161/** @addtogroup bdlb
162 * @{
163 */
164/** @addtogroup bdlb_random
165 * @{
166 */
167
168#include <bdlscm_version.h>
169
171
172#include <bsls_assert.h>
173#include <bsls_review.h>
174
175#include <bsl_cstdint.h>
176
177
178namespace bdlb {
179 // =============
180 // struct Random
181 // =============
182
183/// This `struct` provides a namespace for a suite of functions used for
184/// random-number generation.
185struct Random {
186
187 // CLASS METHODS
188
189 /// Return a 15-bit random number in the range `[ 0 .. 32,767 ]`
190 /// generated from the specified `seed`, and load into the specified
191 /// `nextSeed` a value suitable for generating the next random number.
192 static int generate15(int *nextSeed, int seed);
193
194 /// Return a 15-bit random number in the range `[ 0 .. 32,767 ]`
195 /// generated from the specified `seed`, and load into `seed` a value
196 /// suitable for generating the next random number.
197 static int generate15(int *seed);
198
199 /// Return the next unsigned 32-bit random number generated from the
200 /// specified PCG-based `generator`.
201 static bsl::uint32_t generatePcg(PcgRandomGenerator *generator);
202};
203
204// ============================================================================
205// INLINE DEFINITIONS
206// ============================================================================
207
208 // -------------
209 // struct Random
210 // -------------
211
212// CLASS METHODS
213inline
214int Random::generate15(int *nextSeed, int seed)
215{
216 BSLS_ASSERT(nextSeed);
217
218 unsigned int next = seed;
219
220 next *= 1103515245;
221 next += 12345;
222
223 *nextSeed = next;
224
225 return (next >> 16) & 0x7FFF;
226}
227
228inline
229int Random::generate15(int *seed)
230{
231 BSLS_ASSERT(seed);
232
233 return generate15(seed, *seed);
234}
235
236inline
238{
239 BSLS_ASSERT(generator);
240
241 return generator->generate();
242}
243
244} // close package namespace
245
246
247#endif
248
249// ----------------------------------------------------------------------------
250// Copyright 2015 Bloomberg Finance L.P.
251//
252// Licensed under the Apache License, Version 2.0 (the "License");
253// you may not use this file except in compliance with the License.
254// You may obtain a copy of the License at
255//
256// http://www.apache.org/licenses/LICENSE-2.0
257//
258// Unless required by applicable law or agreed to in writing, software
259// distributed under the License is distributed on an "AS IS" BASIS,
260// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
261// See the License for the specific language governing permissions and
262// limitations under the License.
263// ----------------------------- END-OF-FILE ----------------------------------
264
265/** @} */
266/** @} */
267/** @} */
Definition bdlb_pcgrandomgenerator.h:242
bsl::uint32_t generate()
Definition bdlb_pcgrandomgenerator.h:327
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1804
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition bdlb_algorithmworkaroundutil.h:74
Definition bdlb_random.h:185
static int generate15(int *nextSeed, int seed)
Definition bdlb_random.h:214
static bsl::uint32_t generatePcg(PcgRandomGenerator *generator)
Definition bdlb_random.h:237