C ++: sowing random number generator outside the main ()

I created a simple program that simulates a coin toss for my class. (Actually, the class is working on this term, and I'm just working on other projects that were not needed). It involves creating and calling a function that generates a random number between 1 and 2. Initially, I tried to sow a random number generator inside a function that would use it (coinToss); however, he did not produce a random number. Each time the program started, it was the same as if I used

rand()

instead

 unsigned seed = time(0); srand(seed); rand(); 

However, when I moved higher in

 int main() 

It worked fine.

My question is: 1) why doesn’t it work when setting up inside the called function and (2) how does rand() have access to what was done with srand() if they both do not occur in the same function? Obviously, I'm a newbie, so please forgive me if I did not formulate the question correctly. In addition, my book only briefly touched upon rand() and srand() , so that everything I really know.
Thanks for any help!

Relevant Code:

First attempt that did not work:

 int main() { //........... coinToss(); //........... } int coinToss() { unsigned seed = time(0); srand(seed); return 1 + rand() % 2; } 

The second attempt that worked:

 int main() { unsigned seed = time(0); srand(seed); coinToss(); } int coinToss() { return 1 + rand() % 2; } 
+4
source share
5 answers

You probably only want to split the random number generator. rand() returns the next pseudo-random number from it of the internal generator. Each time you call rand() , you will get the next number from the internal generator.

srand() however sets the initial conditions for the random number generator. You can think of it as setting up a “starting point” for an internal random number generator (actually it is much more complicated than that, but it is a useful cognitive model).

So, you should call srand(time(0)) exactly once in your application - somewhere near the start. After that, you can call rand() as many times as you want!

but

To answer your real question - the first version does not work, because time() returns the number of seconds from the moment. So, if you call coinToss() several times per second (say, if you want to simulate 100 coin throws), you will constantly sow a random number generator with the same number, thereby resetting its internal state (and thus the next number which you get) every time.

In any case, using time() as a seed for srand() is pretty crappy for this very reason - time() does not alternate very often, but worse, it is predictable. If you know the current time, you can decide what rand() will return. There are many, many examples of the best srand() seeds on the Internet.

+9
source

Pseudo-random number generators (e.g. rand ) work by taking one starting number (seed) and performing a numerical conversion on it every time you ask for a new number. Do you want the seeds of the generator only once, or it will constantly receive a reset, which is not what you want.

As you discovered, you should just call srand only once in main . Also note that a number of rand implementations have fairly short loops at low 4 bits or so. In practice, this means that you can get an easily predictable repeating cycle of numbers. You can switch the return from rand to 4-8 bits before you take % 2 .

EDIT: the call would look something like this: return 1 + (rand() >> 6) % 2;

+3
source

Visit only once for each program, and not every time you call coinToss()

+1
source

To expand Mark B's answer: not so that the random number generator is reset, because it sets a new variable that will be used when calculating random numbers. However, your program does not do much work between srand calls. Therefore, every time you call srand (time (0)), it uses the same seed, so you return the internal state of the random number generator. If you slept there so that the time (0) changed, you would not get the same number every time.

As for how data is transferred from srand to rand, it's pretty simple, a global variable is used. All names starting with an underscore and an uppercase letter or two underscores are reserved for the variables used by your compiler. Most likely, this variable was declared static, so it is not visible outside the translation unit (just like a library file containing a standard compiler library). This is done so that #define STUFF 5 does not violate the standard library.

0
source

for simple simulations, you should not change the seed at all during the simulation. In this case, your simulation will be "worse."

To understand this, you should see pseudo-random sequences as a big wheel of luck. When you change the seed, it looks like you are changing the position, and then each call to rand will give you a different number. If you collapse again, it will be more likely to repeat numbers.

0
source

Source: https://habr.com/ru/post/1332274/


All Articles