user1053150
user1053150

Reputation:

random numbers not so random

I have a method in a 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 wasn't getting the behaviour from the program I expected) like so....

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

it's exactly the same number every time it's run (ie, 9,9,9,9,9,....; next run: 43,43,43,43,.....) I don't know what is going wrong. The code runs very quickly so I was thinking that MIGHT be the issue but I don't see why there wouldn't be a difference even slightly between the 20 iterations of it. Any thoughts are appreciated! Thanks!

Upvotes: 7

Views: 883

Answers (3)

bames53
bames53

Reputation: 88155

Cody Gray already says what you're doing wrong here, but here's an example of doing 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 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're less likely to mess it up. Also using uniform_int_distribution gives you unbiased results whereas rand()%50+10 has some slight bias.


If you have a compiler with a bit more C++11 support you can do:

class foo{
   std::mt19937 engine = make_seeded_engine();

public:
   int randomNum10to50(){
      return std::uniform_int_distribution<>(10,50)(engine); 
   }
};

Upvotes: 3

dlev
dlev

Reputation: 48596

You are calling srand() with the same seed every loop iteration, since the time doesn't actually have, um, time to change. Make sure to call it only once and everything should work.

Upvotes: 6

Cody Gray
Cody Gray

Reputation: 244682

You need to call srand() once, outside of the randomizer function. Otherwise, you re-seed the random number generator each time with the exact same time value, producing the same initial "random" value.

Upvotes: 20

Related Questions