1

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?

3
  • Why it matters if n is an unsigned int ? In C++11, there are much better ways to generate random numbers. Commented Sep 7, 2013 at 18:14
  • 1
    Try 1 + rand() % n. Commented Sep 7, 2013 at 18:15
  • Watch rand() Considered Harmful: channel9.msdn.com/Events/GoingNative/2013/… Commented Sep 17, 2013 at 13:59

1 Answer 1

11

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'; } 
Sign up to request clarification or add additional context in comments.

4 Comments

Thank you for your answer. May I ask you once again? My initial problem was to write a function which filled in an array with random numbers in random order. So what I did is
#include <iostream> #include <random> using namespace std; void GenRandArray(int* _result, unsigned int _maxValue) { int i; random_device rd; mt19937 gen(rd()); uniform_int_distribution<> dis1(0, _maxValue - 1); uniform_int_distribution<> dis2(1, _maxValue); for(i = 0; i < _maxValue; i++) _result[ dis1(gen) ] = dis2(gen); } void main() { unsigned int n = 5; int* ar = new int [n]; GenRandArray(ar, n); }
@Igor Why would you want to fill it in random order? Is that really a requirement, because it makes not sense to me.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.