// bdlb_random.h -*-C++-*- // ---------------------------------------------------------------------------- // NOTICE // // This component is not up to date with current BDE coding standards, and // should not be used as an example for new development. // ---------------------------------------------------------------------------- #ifndef INCLUDED_BDLB_RANDOM #define INCLUDED_BDLB_RANDOM #include <bsls_ident.h> BSLS_IDENT("$Id: $") //@PURPOSE: Provide a suite of procedures for random-number generation. // //@CLASSES: // bdlb::Random: namespace for a suite of random-number generation procedures // //@SEE_ALSO: bdlb_pcgrandomgenerator // //@DESCRIPTION: This component provides a utility 'struct', 'bdlb::Random', // that is a namespace for a suite of functions used to efficiently generate // random numbers over a specific range of values. The seed (or current state) // is maintained externally. Two variants of a 15-bit random number generator // are provided: one has a single [in/out] seed parameter, which is first used // then updated; the other takes the current seed as an [input] parameter, and // stores a new seed in an [output] parameter. A third generator produces // 32-bit random numbers employing the PCG algorithm. // ///Usage ///----- // This section illustrates intended use of this component. // ///Example 1: Simulating a Pair of Dice /// - - - - - - - - - - - - - - - - - - // This example shows how one might use 'bdlb::Random' to create and use a // class to simulate the roll of a single die in a game, such as craps, that // uses dice. // // First, we define the 'Die' class itself: //.. // // ========= // // class Die // // ========= // // class Die { // // // DATA // int d_seed; // current state, used to generate next role of this die // // public: // // CREATORS // Die(int initialSeed); // // Create an object used to simulate a single die, using the // // specified 'initialSeed'. // // // MANIPULATORS // int roll(); // // Return the next pseudo-random value in the range '[1 .. 6]', // // based on the sequence of values established by the initial seed // // value supplied at construction. // }; // // // --------- // // class Die // // --------- // // // CREATORS // inline // Die::Die(int initialSeed) // : d_seed(initialSeed) // { // } // // // MANIPULATORS // int Die::roll() // { // int result; // // do { // result = bdlb::Random::generate15(&d_seed) & 7; // } while (result > 5); // // return result + 1; // } //.. // Now, we can use our 'Dice' class to get the random numbers needed to // simulate a game of craps. Note that the game of craps requires two dice. // // We can instantiate a single 'Die' and role it twice, //.. // void rollOneDieTwice() // { // Die a(123); // // int d1 = a.roll(); // int d2 = a.roll(); // // cout << "d1 = " << d1 << ", d2 = " << d2 << endl; // d1 = 3, d2 = 5 // } //.. // Alternatively, we could create two instances of 'Die', with separate initial // seeds, and role each one once: //.. // void rollTwoDice() // { // Die a(123); // Die b(456); // // int d1 = a.roll(); // int d2 = b.roll(); // // cout << "d1 = " << d1 << ", d2 = " << d2 << endl; // d1 = 3, d2 = 1 // } //.. // Note that the specification of separate seeds is important to produce a // proper distribution for our game. If we had shared the seed value each die // would always produce the same sequence of values as the other. //.. // void shareSeed() // { // Die a(123); // BAD IDEA // Die b(123); // BAD IDEA // // int d1 = a.roll(); // int d2 = b.roll(); // assert(d2 == d1); // // } //.. #include <bdlscm_version.h> #include <bdlb_pcgrandomgenerator.h> #include <bsls_assert.h> #include <bsls_review.h> #include <bsl_cstdint.h> namespace BloombergLP { namespace bdlb { // ============= // struct Random // ============= struct Random { // This 'struct' provides a namespace for a suite of functions used for // random-number generation. // CLASS METHODS static int generate15(int *nextSeed, int seed); // Return a 15-bit random number in the range '[ 0 .. 32,767 ]' // generated from the specified 'seed', and load into the specified // 'nextSeed' a value suitable for generating the next random number. static int generate15(int *seed); // Return a 15-bit random number in the range '[ 0 .. 32,767 ]' // generated from the specified 'seed', and load into 'seed' a value // suitable for generating the next random number. static bsl::uint32_t generatePcg(PcgRandomGenerator *generator); // Return the next unsigned 32-bit random number generated from the // specified PCG-based 'generator'. }; // ============================================================================ // INLINE DEFINITIONS // ============================================================================ // ------------- // struct Random // ------------- // CLASS METHODS inline int Random::generate15(int *nextSeed, int seed) { BSLS_ASSERT(nextSeed); unsigned int next = seed; next *= 1103515245; next += 12345; *nextSeed = next; return (next >> 16) & 0x7FFF; } inline int Random::generate15(int *seed) { BSLS_ASSERT(seed); return generate15(seed, *seed); } inline bsl::uint32_t Random::generatePcg(PcgRandomGenerator *generator) { BSLS_ASSERT(generator); return generator->generate(); } } // close package namespace } // close enterprise namespace #endif // ---------------------------------------------------------------------------- // Copyright 2015 Bloomberg Finance L.P. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // ----------------------------- END-OF-FILE ----------------------------------