简体   繁体   中英

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!

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.

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.

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); 
   }
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM