Overblog Suivre ce blog
Editer l'article Administration Créer mon blog
26 mai 2012 6 26 /05 /mai /2012 13:55

Here is a common first year exercice question :

 

Write a function returning a random integer between 0 and n, n being passed as an argument to the function.

 

And here a common answer in C : 

 

 #include <stdlib.h>

// NB. don't forget to initialize with srand()

int random_integer(int n)
{
return (rand() / (RAND_MAX + 1.0) * (n+1));
}

This solution avoids the modulo operation on the value returned by rand() since it is likely to produce a non-uniform number distribution if RAND_MAX is not a multiple of n.

 

Anyway, the shiny new C++11 standard now comes with increased random number facilities located in the random header. Here is how to use them to produced the same result with them :

 

 #include <random> // clearer than stdlib, isn't it ? 

// NB. don't forget to initialize generator with its seed() method

int random_integer(std::mt19937& generator, int n)
{
std::uniform_int_distribution<int> dist_n(0, n);
return dist_n(generator);
}

Some remarks about this design :

  • C++11 standard provides several random number engines which are clearly identified by their names and their fomulas. Users can choose between them depending on their needs instead of trusting the rand() black box. In this example, I used the Mersenne Twister algorithm.
  • There is no shared global engine state like in C. With this design, each thread can have its own random number engine, which is better suited for multicore programming.
  • RNG engines are separated from distributions, which control the probability of a value to be a given range. Notable supported distributions are uniform (used in this article), normal (Gaussian), Poisson, etc.
  • Readability is way improved. Simply reading the dist_n variable declaration is far more understandable than the C equivalent formula.

Partager cet article

Repost 0
Published by Olivier - dans Programmation
commenter cet article

commentaires

Présentation

Recherche

Liens