How to Generate Random Double in C++

Jinku Hu Feb 02, 2024
  1. Use the <random> Library to Generate a Random Double in C++
  2. Use the std::rand Function to Generate a Random Double in C++
  3. Conclusion
How to Generate Random Double in C++

Random number generation is a common requirement in various applications, from simulations to games and statistical modeling.

In C++, there are different approaches to achieve this, and this article will explore methods using both the traditional std::rand function and the more modern <random> header introduced in C++11.

Use the <random> Library to Generate a Random Double in C++

C++ provides a robust and flexible mechanism for random number generation through the <random> header, introduced in C++11. This header offers a more modern and versatile approach compared to the traditional rand() function.

The <random> header introduces a set of classes that encapsulate different random number generation algorithms. Two primary classes are std::random_device and std::mt19937:

The std::random_device class provides a random seed based on some external entropy source (e.g., hardware randomness). It is typically used to seed the random number engine (std::mt19937).

The std::mt19937 class represents the Mersenne Twister pseudo-random number generator. It is initialized with a seed from std::random_device and produces sequences of random numbers.

In order to generate random double values within a specific range, the std::uniform_real_distribution<T> class is employed. This class takes two parameters, representing the inclusive lower and upper bounds of the desired range.

std::uniform_real_distribution<T> distribution(lowerbound, upperbound);

It’s crucial to note that std::uniform_real_distribution<T> exhibits undefined behavior if a type other than float, double, or long double is passed as a template parameter.

Let’s have an example code:

#include <iostream>
#include <random>

int main() {
  std::random_device rd;
  std::mt19937 gen(rd());

  std::uniform_real_distribution<double> dis(10, 100);

  double random_double = dis(gen);

  std::cout << "Random double: " << random_double << std::endl;

  return 0;
}

Firstly, we include the necessary headers, <iostream> for input/output and <random> for the random number generation functionality. These headers provide the tools we need to work with random number generators.

Next, we initiate the random number generation process by creating an instance of std::random_device named rd. This device serves as a source of entropy, providing a seed for our random number generator.

We then create an instance of std::mt19937 named gen and initialize it with the seed from rd. This sets up the Mersenne Twister pseudo-random number generator, a reliable choice for generating random sequences.

Moving on, we define the range for our random double values using the std::uniform_real_distribution<double> class, naming it dis. In our example, the range is set from 10.0 to 100.0. This distribution class ensures that the generated doubles are uniformly distributed within the specified range.

Now, we’re ready to generate the actual random double. We call the operator() of our distribution object (dis) and pass the generator (gen) as an argument, which produces a random double value within the predefined range.

Output:

Random double: 97.5907

This approach provides better control and distribution characteristics than the traditional rand() function, making it a preferred choice for modern C++ applications.

Use the std::rand Function to Generate a Random Double in C++

While modern C++ standards introduce more sophisticated methods for random number generation using the <random> header, the traditional std::rand function remains a simple option for basic scenarios.

The std::rand function is part of the <cstdlib> header and is used to generate pseudo-random integers. To obtain a random double within a specific range, we typically use the modulo operator and scaling.

The basic syntax involves calling std::rand() and manipulating the result:

double random_double = static_cast<double>(std::rand()) / RAND_MAX;

Here, std::rand() generates an integer, and RAND_MAX is the maximum value that std::rand can return. By dividing the result by RAND_MAX and casting it to a double, we obtain a random double in the range [0, 1).

Here’s a complete working code example:

#include <cstdlib>
#include <ctime>
#include <iostream>

int main() {
  std::srand(std::time(0));

  double random_double = static_cast<double>(std::rand()) / RAND_MAX;

  std::cout << "Random double: " << random_double << std::endl;

  return 0;
}

In this example, we begin by including the necessary headers: <iostream> for input/output, <cstdlib> for the std::rand function, and <ctime> for seeding the random number generator based on the current time.

The std::srand(std::time(0)) call seeds the random number generator with the current time, ensuring different sequences of random numbers on each program run. Following this, we use std::rand() to generate a pseudo-random integer.

To convert this integer to a double within the range [0, 1), we divide it by RAND_MAX and cast the result to a double. Finally, we display the generated random double using std::cout.

Output:

Random double: 0.569786

While std::rand is straightforward, it’s important to note that it has limitations. The distribution of generated numbers may not be as uniform or predictable as with more modern methods from the <random> header.

Additionally, it’s sensitive to the seed value, and careful seeding practices are necessary for better randomness. For more advanced use cases, especially in modern C++, consider using the <random> header for improved control and distribution characteristics.

Conclusion

Both methods discussed above have their merits.

The traditional std::rand is simple but has limitations in terms of distribution and predictability. The <random> header provides more control and better distribution characteristics.

When possible, prefer the <random> header, especially in modern C++ applications. It offers a robust and flexible framework for various random number generation needs.

Author: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook

Related Article - C++ Double