Random numbers, not so random

I have a method in the class as follows:

class foo{ int bar::randomNum10to50(){ srand (time(NULL)); int random10to50 = rand()%50+10; return random10to50; } } 

However, when I call it from main (just to check the output, because I did not get the behavior from the expected program), so ...

 foo create; for (int i=0; i<20;i++){ cout<<create.randomNum10to50()<<endl; } 

this is exactly the same number every time it starts (i.e. 9,9,9,9,9,9, ....; the following run: 43,43,43,43, .....) I know what is going wrong. The code is very fast, so I thought it MAY be a problem, but I don’t understand why there would be no difference between the 20 iterations. Any thoughts are appreciated! Thanks!

+7
source share
3 answers

You need to call srand() once, outside the randomizer function. Otherwise, each time you restart the random number generator with exactly the same time value, creating the same initial "random" value.

+20
source

You call srand() with the same seed of each iteration of the loop, because time does not really have, um, time to change. Be sure to call it only once, and everything should work.

+6
source

Cody Gray already says what you are doing wrong here, but here is an example of this with the <random> library:

 #include <random> std::mt19937 make_seeded_engine() { std::random_device r; std::seed_seq seed{r(), r(), r(), r(), r(), r(), r(), r()}; return std::mt19937(seed); } class foo { std::mt19937 engine; public: foo() : engine(make_seeded_engine()) {} int randomNum10to50(){ return std::uniform_int_distribution<>(10,50)(engine); } }; foo create; for (int i=0; i<20;i++){ cout << create.randomNum10to50() << '\n'; } 

Note that rand()%50 + 10 produces numbers in the range of 10 to 59, not 10 to 50. uniform_int_distribution is better because the range you give it is the range you get, so you are unlikely spoil it. In addition, using uniform_int_distribution gives unbiased results, while rand()%50+10 has a slight deviation.


If you have a compiler with support for more than C ++ 11, you can do:

 class foo{ std::mt19937 engine = make_seeded_engine(); public: int randomNum10to50(){ return std::uniform_int_distribution<>(10,50)(engine); } }; 
+3
source

All Articles