c++randomsrand

rand() not giving me a random number (even when srand() is used)


Okay I'm starting to lose my mind. All I want to do is random a number between 0 and 410, and according to this page, my code should do that. And since I want a random number and not a pseudo-random number, I'm using srand() as well, in a way that e.g. this thread told me to do. But this isn't working. All I get is a number that is depending on how long it was since my last execution. If I e.g. execute it again as fast as I can, the number is usually 6 numbers higher than the last number, and if I wait longer, it's higher, etc. When it reaches 410 it goes back to 0 and begins all over again. What am I missing?

Edit: And oh, if I remove the srand(time(NULL)); line I just get the same number (41) every time I run the program. That's not even pseudo random, that's just a static number. Just copying the first line of code from the article I linked to above still gives me number 41 all the time. Am I the star in a sequel to "The Number 23", or have I missed something?

int main(void) {

    srand(time(NULL));
    int number = rand() % 410;

    std::cout << number << std::endl;

    system("pause");

}

Solution

  • That is what you get for using deprecated random number generation.

    rand produces a fixed sequence of numbers (which by itself is fine), and does that very, very badly.

    You tell rand via srand where in the sequence to start. Since your "starting point" (called seed btw) depends on the number of seconds since 1.1.1970 0:00:00 UTC, your output is obviously time depended.

    The correct way to do what you want to do is using the C++11 <random> library. In your concrete example, this would look somewhat like this:

    std::mt19937 rng (std::random_device{}());
    std::uniform_int_distribution<> dist (0, 409);
    
    auto random_number = dist(rng);
    

    For more information on the evils of rand and the advantages of <random> have a look at this.

    As a last remark, seeding std::mt19937 like I did above is not quite optimal because the MT's state space is much larger than the 32 bit you get out of a single call to std::random_device{}(). This is not a problem for toy programs and your standard school assignments, but for reference: Here is my take at seeding the MT's entire state space, plus some helpful suggestions in the answers.