For working professionals
For fresh graduates
More
4. C++ Variable
10. C++ for Loop
12. C++ Lambda
13. Loop in C++
15. Array in C++
16. Strings in C++
17. Substring in C++
29. Vector in C++
30. Map in C++
31. Pair in C++
33. Iterators in C++
34. Queue in C++
36. Stack in C++
37. ifstream in C++
40. Templates in C++
43. Namespace in C++
46. Recursion in C++
48. C++ Shell
49. Setw in C++
51. Atoi in C++
54. C# vs C++
55. C++ GUI
56. C++ Game Code
57. Class in C++
58. C++ Header Files
63. Cin in C++
64. Printf in C++
65. Struct in C++
66. C++ List
68. C++ Comments
72. Sorting in C++
Random numbers are a core component behind a lot of applications, injecting unpredictability and variety into software. They are indispensable for simulations, gaming, cryptography, statistical sampling, and numerous algorithms. Random number generators are essential in programming in general, similarly being extremely useful in C++ programs as well.
In this tutorial, I will discuss the different types of random number engines available in C++ and how to generate numbers that are random in cpp. We will then explore the concept of seeding and its crucial role in ensuring the quality and variability of our random number sequences. Finally, we'll also examine various probability distributions and demonstrate how to use them to generate random numbers tailored to our specific applications.
Let us dive in and learn about working with a random number generator in C++.
Simulations rely on randomness to model real-world scenarios with accurate variations, while games utilize random number generation to create engaging and unpredictable experiences. In cryptography, randomness ensures robust security, while statistical sampling depends on it for fair and representative data collection.
However, it is important to understand the distinction between true randomness and pseudorandomness. True randomness stems from unpredictable physical phenomena, such as atmospheric noise or quantum effects, and is inherently non-deterministic. In contrast, pseudorandomness relies on algorithms to generate sequences of numbers that appear random but are, in fact, deterministic and repeatable given the same starting conditions.
C++, while capable of utilizing true random data sources, primarily focuses on providing powerful and efficient mechanisms for generating pseudorandom numbers. The Standard Library allows us to work with numbers that are random in C++, specifically the <random> header introduced in C++11, equips developers with a comprehensive toolkit for generating high-quality pseudorandom numbers with excellent statistical properties. This toolkit includes various random number engines, which serve as the core generators of random values, and distributions, which shape the output of these engines to fit specific needs.
The <random> header, introduced in C++11, revolutionized random number generation in C++, offering a flexible and powerful framework for creating high-quality pseudorandom values. This header provides two main building blocks: random number engines and distributions.
Random number engines are the core generators of pseudorandom values in C++. They act as the source of randomness, producing sequences of numbers that appear unpredictable. Think of them as the "powerhouse" that fuels the random number generation process. The <random> header offers several engine options:
While engines generate random numbers, they often produce values within a specific range (e.g., between 0 and a large maximum value). Distributions come into play to transform this raw output into numbers that follow specific probability distributions, making them suitable for different tasks.
Here are some commonly used distributions:
The true strength of the <random> header lies in its flexibility. By combining different engines with various distributions, we can create a wide array of tailored random number generators, perfectly suited to our specific needs. This modular approach allows us to select the best engine for performance and the ideal distribution for the statistical properties we require.
Now that we have explored the building blocks of cpp random number generation, let us put them together to generate random values that meet our specific requirements. Follow these five steps:
1. Include <random>
The first step is to ensure that our C++ code has access to the powerful tools in the <random> header. Include it at the beginning of your file:
#include <random> |
2. Choose an Engine
Select a random number engine that balances your needs for speed and randomness quality. Here are common choices:
Create an instance of your chosen engine:
std::mt19937 rng; // Mersenne Twister engine |
3. Seed the Engine
Seeding is the process of initializing the engine with a starting value. This ensures that the sequence of random numbers we generate is different each time we run our program.
A good practice is to use std::random_device for obtaining a truly random seed:
std::random_device rd;
std::mt19937 rng(rd());
If std::random_device is not available, we can use the current time as a seed (though less ideal):
std::mt19937 rng(std::time(0)); |
4. Choose a Distribution
Determine the range and type of random values you need. Select the appropriate distribution:
Create a distribution object, specifying its parameters (if needed):
std::uniform_int_distribution<int> dist(1, 6); // 1 to 6 (inclusive) |
Finally, use the engine and distribution together to generate random values:
int randomValue = dist(rng); // Generate a random value using the engine |
Repeat this as needed within a loop or call it on-demand to generate individual random numbers. Finally, we should always remember that thoughtful seeding and appropriate distribution selection are crucial for obtaining high-quality random numbers that suit our specific needs.
Code:
#include <iostream>
#include <random>
int main() {
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dist(1, 6); // Distribution for values 1 to 6
std::cout << "Rolling a die 10 times: ";
for (int i = 0; i < 10; ++i) {
std::cout << dist(gen) << " ";
}
std::cout << std::endl;
}
We use a random device to seed a Mersenne Twister engine (std::mt19937). Then, we create a uniform integer distribution (std::uniform_int_distribution) to generate random values from 1 to 6 (inclusive), simulating the roll of a standard die.
If you wish to learn how to code in C++, you can check out upGrad’s software engineering courses.
Code:
#include <iostream>
#include <random>
int main() {
std::random_device rd;
std::mt19937 gen(rd());
// 2D point (x, y) between 0.0 and 100.0
std::uniform_real_distribution<> distX(0.0, 100.0);
std::uniform_real_distribution<> distY(0.0, 100.0);
for (int i = 0; i < 5; ++i) {
double x = distX(gen);
double y = distY(gen);
std::cout << "Point " << i + 1 << ": (" << x << ", " << y << ")\n";
}
}
Similar to the dice roll example, we seed an engine and then create two separate uniform real distributions (std::uniform_real_distribution) to generate random x and y coordinates between 0.0 and 100.0, producing five random points in a 2D space.
Code:
#include <iostream>
#include <random>
#include <vector>
#include <algorithm>
int main() {
std::vector<std::string> deck = {"Ace", "2", "3", /* ... , */ "King"};
std::random_device rd;
std::mt19937 gen(rd());
std::shuffle(deck.begin(), deck.end(), gen); // Shuffle the deck
std::cout << "Shuffled deck:\n";
for (const std::string& card : deck) {
std::cout << card << " ";
}
std::cout << std::endl;
}
We create a vector representing a deck of cards. We use the std::shuffle algorithm from the <algorithm> header, which takes our random number engine (gen) as a parameter to randomly reorder the elements in the deck.
Generating random numbers may seem simple, but there are nuances that can significantly impact the quality and predictability of our results. Adhering to best practices ensures our random numbers are as random as we need them to be.
Seeding our random number engine is like giving it a starting point for its calculations. A good seed ensures that the generated sequence appears unpredictable and varies between different program runs. Here is what we need to know:
std::random_device rd;
std::mt19937 gen(rd());
std::mt19937 gen(std::time(0)); |
Choosing the right probability distribution is crucial for achieving the desired behavior in our random numbers. Consider the following:
You can explore the <random> header for a wide range of other distributions. To experiment more, you can try to work on a custom random number generator in C++ within a range.
Selecting the appropriate cpp random number engine and distribution is crucial. We should always consider factors like performance, statistical quality, and the desired range and type of our random numbers.
I also find it extremely important to mention that we must always seed our random number engine to ensure unpredictable sequences. We can favor std::random_device for truly random seeds, or use system time as a fallback if necessary. Finally, we should steer clear of the outdated rand() function, and avoid incorrect seeding or frequent re-seeding practices.
By following these guidelines and adhering to the best practices I discussed, we can guarantee that our random number generation is both reliable and high-quality in C++ programming. Gaining expertise in working with random number generator in C++ will also set the stage for robust simulations, engaging games, and secure cryptographic applications.
Embrace the power of randomness, and let your C++ code flourish with unpredictability. If you wish to learn programming languages such as C++, you can check out upGrad’s computer science programs such as the Master’s in Computer Science Program.
In C++, a random number generator (RNG) is a mechanism (usually an algorithm) for producing a sequence of numbers that lack any discernible pattern.
You combine a random number engine (like std::mt19937) with a distribution (like std::uniform_int_distribution) from the <random> header.
For most applications, the std::mt19937 engine provides a good balance of speed and statistical quality.
The rand() function is an older, C-style way to generate random numbers, but it's less flexible and has potential quality issues compared to modern C++ methods.
True randomness requires external sources like hardware noise or atmospheric data, but you can approximate it with techniques like linear congruential generators (though less reliable than modern RNGs).
Use the classes and functions in the <random> header, which provides a much more robust and flexible framework for random number generation.
No, the random numbers generated by C++ algorithms are pseudorandom – they follow a deterministic pattern but appear random for practical purposes.
No, the standard C++ random number generators are not cryptographically secure. You need specialized libraries for generating cryptographically secure random numbers.
Author
Start Learning For Free
Explore Our Free Software Tutorials and Elevate your Career.
Talk to our experts. We are available 7 days a week, 9 AM to 12 AM (midnight)
Indian Nationals
1800 210 2020
Foreign Nationals
+918045604032
1.The above statistics depend on various factors and individual results may vary. Past performance is no guarantee of future results.
2.The student assumes full responsibility for all expenses associated with visas, travel, & related costs. upGrad does not provide any a.