最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c++ - Why does rand() produce different numbers in a loop despite srand() being set once at the beginning of the program? - Stac

programmeradmin4浏览0评论

I made a program that produces a different random number 10 times.
Here is the code:

#include <iostream>
#include <cstdlib>
#include <ctime>

int main() {
    srand(time(0));
    for (int i = 0; i <10; i++) {
        
        std::cout << rand() % 100 << std::endl;
    }
    return 0;
}

It runs fine. However, I do not understand why. I did some research and based on what I understand:

  • rand() is always seeded to 1, which therefore produces the same number
  • In order to generate different results, I have to seed it with something different(like the time) by doing this : srand(time(0))

My concern is: if I set the seed once outside the loop, shouldn't rand() produce the same number? Because based on what I know, rand() gives pseudo-random numbers, which are "fake", and I understood that it follows a certain predictable algorithm, which means that in every iteration of the loop it uses the same seed set outside the loop which is supposed to give me the same numbers. Why would I get different numbers?

I made a program that produces a different random number 10 times.
Here is the code:

#include <iostream>
#include <cstdlib>
#include <ctime>

int main() {
    srand(time(0));
    for (int i = 0; i <10; i++) {
        
        std::cout << rand() % 100 << std::endl;
    }
    return 0;
}

It runs fine. However, I do not understand why. I did some research and based on what I understand:

  • rand() is always seeded to 1, which therefore produces the same number
  • In order to generate different results, I have to seed it with something different(like the time) by doing this : srand(time(0))

My concern is: if I set the seed once outside the loop, shouldn't rand() produce the same number? Because based on what I know, rand() gives pseudo-random numbers, which are "fake", and I understood that it follows a certain predictable algorithm, which means that in every iteration of the loop it uses the same seed set outside the loop which is supposed to give me the same numbers. Why would I get different numbers?

Share Improve this question edited Feb 16 at 12:33 wohlstad 28.5k16 gold badges58 silver badges87 bronze badges asked Feb 16 at 10:40 Mohamad KhalilMohamad Khalil 211 silver badge8 bronze badges 9
  • 2 The seed only (more or less) determines the starting point of the pseudo random numbers sequence. The values in the sequence (that you get by the calls to rand()) will still be different. In any case it is recommended to use <random> instead of rand() in C++. See here: stackoverflow/questions/13445688/…. – wohlstad Commented Feb 16 at 10:43
  • Could you elaborate further? And, why not write a full answer? @wohlstad – Mohamad Khalil Commented Feb 16 at 10:46
  • Posted an answer as requested. – wohlstad Commented Feb 16 at 10:54
  • @wohlstad I appreciate it, and thanks for the side note. – Mohamad Khalil Commented Feb 16 at 10:56
  • time(0) gives you a different starting point each time you run the program, so different random numbers. – BoP Commented Feb 16 at 12:11
 |  Show 4 more comments

3 Answers 3

Reset to default 6

srand() is seeding the random generator.
This means that for every seed there will be a sequence of pseudo random values that the generator can produce (not a single value).
Every call to rand() will return the next value in the sequence.

The documentation explicitly mentions that:

Generally speaking, the pseudo-random number generator should only be seeded once, before any calls to rand(), at the start of the program. It should not be repeatedly seeded, or reseeded every time you wish to generate a new batch of pseudo-random numbers.

Therefore calling srand() once is not only OK in your case, it is actually the recommended way.

A side note:
In C++ is it recommended to use <random> instead of the lagacy rand().
See more info here: How to generate a random number in C++?.

A pseudo random number generator such as rand has indeed a behavior defined by its seed. However, this behavior is not just a single output, but a sequence of outputs.

Internally, a PRNG is a numeric sequence, and the seed influences how this sequence starts (and, possibly, how it evolves). From there, the machinery transforms each successive result in a deterministic but seemingly random way.

You can try this yourself: in your program, give a fixed arbitrary number to srand and you'll see that each time you run your program, you'll get the same output!

A really bad implementation of rand (but still meeting the requirements of the standard) could look something like this:

#include <iostream>
#include <cstdlib>
#include <ctime>

unsigned randomState = 1;
const int MY_RAND_MAX = 0x7FFFFFF;

void mysrand(unsigned seed)
{
    randomState = seed;
}

int myrand()
{
    randomState += 3150171407;
    return (int)(randomState & MY_RAND_MAX);
}

int main() {
    mysrand(time(0));
    for (int i = 0; i <10; i++) {
        
        std::cout << myrand() % 100 << std::endl;
    }
    return 0;
}

srand initialises the random number generators internal state using the specified value. Each call to rand then applies some algorithm to the internal state, modifying the state and returning a psuedo-random number. The next call to rand will start from the now modified state and produce a different number.

Hopefully your standard library's implementation of rand is higher quality than mine but it'll basically follow the same pattern with just a more appropriate algorithm used inside rand.

There's no guarantee that the standard library does have a good quality implementation see Why is the use of rand() considered bad. Using rand() % 100 will make rand's output even worse, lower numbers will be more likely to be produced than higher ones due to biases introduced by using modulus. Both issues can be fixed by using the c++11 standard library random number generation.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论