As the title suggests, I am trying to figure out a way of generating random numbers using the new C++11 <random>
library. I have tried it with this code:
std::default_random_engine generator;
std::uniform_real_distribution<double> uniform_distance(1, 10.001);
The problem with the code I have is that every time I compile and run it, it always generates the same numbers. So my question is what other functions in the random library can accomplish this while being truly random?
For my particular use case, I was trying to get a value within the range [1, 10]
In C++11, we can get the random library to generate random numbers. Here we have used random_device once to seed the random number generator object called mt. This random_device is slower than the mt19937, but we do not need to seed it. It requests for random data to the operating system.
One way to generate these numbers in C++ is to use the function rand(). Rand is defined as: #include <cstdlib> int rand(); The rand function takes no arguments and returns an integer that is a pseudo-random number between 0 and RAND_MAX.
rand() rand() function is an inbuilt function in C++ STL, which is defined in header file <cstdlib>. rand() is used to generate a series of random numbers. The random number is generated by using an algorithm that gives a series of non-related numbers whenever this function is called.
How to Generate Random Numbers in C++ Within a Range. Similar to 1 and 10, you can generate random numbers within any range using the modulus operator. For instance, to generate numbers between 1 and 100, you can write int random = 1+ (rand() % 100).
In C++11, we can get the random library to generate random numbers. Here we have used random_device once to seed the random number generator object called mt. This random_device is slower than the mt19937, but we do not need to seed it. It requests for random data to the operating system.
With the help of rand () a number in range can be generated as num = (rand () % (upper – lower + 1)) + lower // random number in a given range.
Some programs need numbers that reflect a nonuniform distribution. Programmers often introduce nonrandomness when they try to transform the range, type, or distribution of the numbers generated by rand. (quote from Lippmans C++ primer fifth edition 2012)
As C does not have an inbuilt function for generating a number in the range, but it does have rand function which generate a random number from 0 to RAND_MAX. With the help of rand () a number in range can be generated as num = (rand () % (upper – lower + 1)) + lower
Stephan T. Lavavej(stl) from Microsoft did a talk at Going Native about how to use the new C++11 random functions and why not to use rand()
. In it, he included a slide that basically solves your question. I've copied the code from that slide below.
You can see his full talk here:
#include <random>
#include <iostream>
int main() {
std::random_device rd;
std::mt19937 mt(rd());
std::uniform_real_distribution<double> dist(1.0, 10.0);
for (int i=0; i<16; ++i)
std::cout << dist(mt) << "\n";
}
We use random_device
once to seed the random number generator named mt
. random_device()
is slower than mt19937
, but it does not need to be seeded because it requests random data from your operating system (which will source from various locations, like RdRand for example).
Looking at this question / answer, it appears that uniform_real_distribution
returns a number in the range [a, b)
, where you want [a, b]
. To do that, our uniform_real_distibution
should actually look like:
std::uniform_real_distribution<double> dist(1, std::nextafter(10, DBL_MAX));
My 'random' library provide a high convenient wrapper around C++11 random classes. You can do almost all things with a simple 'get' method.
Examples:
Random number in a range
auto val = Random::get(-10, 10); // Integer
auto val = Random::get(10.f, -10.f); // Float point
Random boolean
auto val = Random::get<bool>( ) // 50% to generate true
auto val = Random::get<bool>( 0.7 ) // 70% to generate true
Random value from a std::initilizer_list
auto val = Random::get( { 1, 3, 5, 7, 9 } ); // val = 1 or 3 or...
Random iterator from iterator range or all container
auto it = Random::get( vec.begin(), vec.end() ); // it = random iterator
auto it = Random::get( vec ); // return random iterator
And even more things ! Check out the github page:
https://github.com/effolkronium/random
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With