Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Random number generator, C++

Tags:

c++

random

I know there is a bit of limitations for a random number generation in C++ (can be non-uniform). How can I generate a number from 1 to 14620?

Thank you.

like image 799
notrockstar Avatar asked Feb 16 '11 16:02

notrockstar


2 Answers

If you've got a c++0x environment, a close derivative of the boost lib is now standard:

#include <random>
#include <iostream>

int main()
{
    std::uniform_int_distribution<> d(1, 14620);
    std::mt19937 gen;
    std::cout << d(gen) << '\n';
}

This will be fast, easy and high quality.

You didn't specify, but if you wanted floating point instead just sub in:

std::uniform_real_distribution<> d(1, 14620);

And if you needed a non-uniform distribution, you can build your own piece-wise constant or piece-wise linear distribution very easily.

like image 183
Howard Hinnant Avatar answered Oct 04 '22 21:10

Howard Hinnant


A common approach is to use std::rand() with a modulo:

#include<cstdlib>
#include<ctime>

// ...
std::srand(std::time(0));  // needed once per program run
int r = std::rand() % 14620 + 1;

However, as @tenfour mentions in his answer, the modulo operator can disrupt the uniformity of values std::rand() returns. This is because the modulo translates the values it discards into valid values, and this translation might not be uniform. For instance, for n in [0, 10) the value n % 9 translates 9 to 0, so you can get zero by either a true zero or a 9 translated to zero. The other values have each only one chance to yield.

An alternative approach is to translate the random number from std::rand() to a floating-point value in the range [0, 1) and then translate and shift the value to within the range you desire.

int r = static_cast<double>(std::rand()) / RAND_MAX * 14620) + 1;
like image 24
wilhelmtell Avatar answered Oct 04 '22 22:10

wilhelmtell