Igor
Igor

Reputation: 23

generating random numbers in c++

I need to generate a random number between 1 and n where n is unsigned int. If n were int I would simply write 1 + rand()% n. But unfortunately n is unsigned int. What do you suggest?

Upvotes: 1

Views: 2407

Answers (1)

cooky451
cooky451

Reputation: 3510

rand() should be avoided whenever possible*. Use http://en.cppreference.com/w/cpp/numeric/random

#include <random>
#include <iostream>


int main()
{
    std::random_device rd;
    std::mt19937 engine(rd());
    std::uniform_int_distribution<unsigned> dist(1, 77);

    for (int i = 0; i != 5; ++i)
        std::cout << dist(engine) << '\n';
}

* Because it shares a global state, gets often implemented as a linear congruential engine which has a few drawbacks and it's range is often only 0-2^16. Also, % n where n is not an exact multiple of the range does not produce an uniform distribution.

Edit: This might seem like overkill, but technically one would want something like this, since mt19937 needs a bit of "warm up":

std::mt19937 create_seeded_rng() 
{ 
    std::random_device rd; 
    std::array<std::mt19937::result_type, std::mt19937::state_size> seed_data; 
    std::generate(seed_data.begin(), seed_data.end(), std::ref(rd)); 
    std::seed_seq seq(seed_data.begin(), seed_data.end()); 
    return std::mt19937(seq); 
} 

int main() 
{ 
    std::mt19937 rng = create_seeded_rng(); 
    std::uniform_int_distribution<int> dist(0, 100); 

    for (unsigned i = 0; i != 100; ++i) 
        std::cout << dist(rng) << '\n'; 
}

Upvotes: 11

Related Questions