Table of Contents
1. Introduction
Generating random numbers within a specific range is a common task in C++ programming. The requirement often involves creating random integers or floating-point numbers within a range, like 1 to 10. This article will explore various methods to generate random numbers between 0 and 1(inclusive and exclusive both)
The numbers generated are fractions, so they will be either float or double values.
2. Using the rand() Function
C++ programming language comes with an in-built pseudo-random number generator (PRNG)
along with rand ()
and srand ()
functions which can be used to generate random numbers.
The rand()
function, found in the <cstdlib>
header, generates a random number.
To generate random number between 0 and 1, we use the following code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
#include <cstdlib> #include <iostream> #include <ctime> int main() { srand(static_cast<unsigned int>(time(0))); // Initialize random seed double randomNumber = (float)rand() / (float)RAND_MAX; std::cout << "Random Number: " << randomNumber << std::endl; return 0; } |
Output:
1 2 3 |
Random Number: 0.999441 |
When we invoke srand(time(0))
, we’re essentially telling the random number generator to start with a seed based on the current time. This means that each time we run our program, time(0)
will likely return a different value, leading to a different starting point for the random number sequence. As a result, the sequence of numbers generated by rand() will be different in each run.
Let’s understand srand()
and rand()
functions a little bit in detail.
Srand()
: This function takes the initial value which is used by rand()
to create random numbers. It’s called only once, to initiate the process of random number.
Rand()
: This function is used to generate random numbers. It is called several times until we want to generate random numbers. Provides a sequence of random numbers every time it is called.
Another thing to remember is that the above method will exclude 1 as random numbers.To include 1 from random numbers, we can subtract 1.0 in the denominator making it (float)(RAND_MAX - 1.0)
.
3, Using C++11 <random> Library
C++11
introduced a more robust random library in <random>
. It provides a more uniform and reliable distribution of random numbers than rand()
function. It allows more control and produces a better distribution of random numbers.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#include <random> #include <iostream> int main() { std::random_device rd; std::mt19937 eng(rd()); std::uniform_real_distribution<> distr(0, 1); double randomNumber = distr(eng); std::cout << "Random Number: " << randomNumber << std::endl; return 0; } |
Output:
1 2 3 |
Random Number: 0.10844 |
Let’s understand more about code in 3 sections.
-
Initializing the Random Number Generator:
std::random_device rd
: Creates an instance of std::random_device. This object provides a source of non-deterministic random numbers (often based on hardware entropy sources), which we use to seed our random number generator.std::mt19937 eng(rd())
: Creates a Mersenne Twister random number generator engine (std::mt19937) seeded with the random value generated by rd. The Mersenne Twister is a popular choice for generating pseudo-random numbers due to its high quality and fast performance.
-
Setting Up the Distribution:
- std::uniform_real_distribution<> distr(0, 1);: This defines a uniform real distribution between 0 and 1. This distribution generates floating-point numbers in the range [0, 1), meaning it includes 0 but excludes 1. The <> is a template that by default takes double as its type.
-
Generating the Random Number:
double randomNumber = distr(eng);
: This line generates a random number. The distr object is called with the Mersenne Twister engine eng as an argument. This yields a random floating-point number in the range [0, 1).
To include 1 in random number, we need to adjust the range in std::uniform_real_distribution
‘s constructor as below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
#include <random> #include <iostream> int main() { std::random_device rd; std::mt19937 eng(rd()); // Adjust the upper bound to include 1 std::uniform_real_distribution<> distr(0, std::nextafter(1, DBL_MAX)); double randomNumber = distr(eng); std::cout << "Random Number: " << randomNumber << std::endl; return 0; } |
4. Performance Comparison
Using rand() Function: This method is generally faster due to its simplicity but at the cost of potentially less uniform distribution and randomness quality.
Using C++11 <random> Library: While this might be marginally slower due to its more complex nature, it provides a significantly better distribution and quality of randomness, making it the preferred choice for applications where randomness quality is important.
5. Conclusion
Choosing the right method for generating a random number between 0 and 1 in C++ depends on the specific requirements of our application. If we’re working on simple, small-scale projects or where high-quality randomness isn’t crucial, using the rand()
function is sufficient and straightforward. However, for more serious applications, especially those requiring more reliable and uniform random number generation, the C++11 <random> library is a superior choice. It offers not only better randomness but also more options to tailor the random number generation process to your specific needs.