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.
#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:
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.
#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:
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:
#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.