6.9 C++11 Random Numbers

According to CERT, function rand does not have “good statistical properties” and can be predictable, which makes programs that use rand less secure (CERT guideline MSC50-CPP). C++11 provides a more secure library of random-number capabilities that can produce nondeterministic random numbers—a set of random numbers that can’t be predicted. Such random-number generators are used in simulations and security scenarios where predictability is undesirable. These new capabilities are located in the C++ Standard Library’s <random> header.

Random-number generation is a mathematically sophisticated topic for which mathematicians have developed many random-number generation algorithms with different statistical properties. For flexibility based on how random numbers are used in programs, C++11 provides many classes that represent various random-number generation engines and distributions. An engine implements a random-number generation algorithm that produces pseudorandom numbers. A distribution controls the range of values produced by an engine, the types of those values (e.g., int, double, etc.) and the statistical properties of the values. In this section, we’ll use the default random-number generation engine—default_random_engine—and a uniform_int_distribution, which evenly distributes pseudorandom integers over a specified range of values. The default range is from 0 to the maximum value of an int on your platform.

Rolling a Six-Sided Die

Figure 6.10 uses the default_random_engine and the uniform_int_distribution to roll a six-sided die. Line 13 creates a default_random_engine object named engine. Its constructor argument seeds the random-number generation engine with the current time. If you don’t pass a value to the constructor, the default seed will be used and the program will produce the same sequence of numbers each time it executes—this is useful for testing purposes. Line 14 creates randomInt—a uniform_int_distribution object that produces unsigned int values (as specified by <unsigned int>) in the range 1 to 6 (as specified by the constructor arguments). The expression randomInt(engine) (line 19) returns one unsigned int value in the range 1 to 6.

Fig. 6.10 Using a C++11 random-number generation engine and distribution to roll a six-sided die.

Alternate View

 1   // Fig. 6.10: fig06_10.cpp
 2   // Using a C++11 random-number generation engine and distribution
 3   // to roll a six-sided die.
 4   #include <iostream>
 5   #include <iomanip>
 6   #include <random> // contains C++11 random number generation features
 7   #include <ctime>
 8   using namespace std;
 9
10   int main() {
11      // use the default random-number generation engine to                
12      // produce uniformly distributed pseudorandom int values from 1 to 6 
13      default_random_engine engine{static_cast<unsigned int>(time(0))};    
14      uniform_int_distribution<unsigned int> randomInt{1, 6};              
15
16      // loop 10 times
17      for (unsigned int counter{1}; counter <= 10; ++counter) {
18         // pick random number from 1 to 6 and output it
19         cout << setw(10) << randomInt(engine);
20
21         // if counter is divisible by 5, start a new line of output
22         if (counter % 5 == 0) {
23            cout << endl;
24         }
25      }
26   }

         2        1        2        3        5
         6        1        5        6        4

The notation <unsigned int> in line 14 indicates that uniform_int_distribution is a class template. In this case, any integer type can be specified in the angle brackets (< and >). In Chapter 18, we discuss how to create class templates and various other chapters show how to use existing class templates from the C++ Standard Library. For now, you should feel comfortable using class template uniform_int_distribution by mimicking the syntax shown in the example.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset