-1
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void sep_gen(void);

int main()
{
srandom((unsigned)time(NULL));
printf("Random Numbers\n");

sep_gen();
sep_gen();
sep_gen();

return(0);
}

void sep_gen(void)
{
long int r;
int i;

for (i=0;i<10;i++)
    putchar('-');
putchar('\n');

r=random();
printf("%ld\n",r);
}

The above code generates three different integers as intended. However, when the srandom((unsigned)time(NULL)) is used sep_gen() function, the integers generated are the same all the three times. (Code below)

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void sep_gen(void);

int main()
{
printf("Random Numbers\n");

sep_gen();
sep_gen();
sep_gen();

return(0);
}

void sep_gen(void)
{

srandom((unsigned)time(NULL));
long int r;
int i;

for (i=0;i<10;i++)
    putchar('-');
putchar('\n');

r=random();
printf("%ld\n",r);
}

My question why is that random() function generates different numbers when the srandom() functioned is placed in the main function, but doesn't do so when in sep_gen() function?

ShadowRanger
  • 143,180
  • 12
  • 188
  • 271
Arshitha
  • 33
  • 1
  • 8
  • `srandom` is no standard function. – too honest for this site Mar 25 '16 at 22:46
  • @Olaf: It's part of POSIX.1-2001 according to [the man page](http://linux.die.net/man/3/srandom). Not sure why it matters. – ShadowRanger Mar 25 '16 at 22:54
  • @ShadowRanger: See [ask] and what a [mcve] is. There is an appropriate tag for e.g. POSIX, otherwise it should be in the text. – too honest for this site Mar 25 '16 at 23:16
  • 1
    @Olaf: Wow, that's absurdly nitpicky. `srandom` is not some wildly obscure function, and expecting a relatively new user to be perfect about calling it out as a POSIX function is silly. – ShadowRanger Mar 25 '16 at 23:21
  • @ShadowRanger: A comment is for clarification and request adding relevant information to the question. You are aware this is read by other beginners, too, are you? One cannot assume everyone is aware of the POSIX functions and very well might wonder what `random` and `srandom` actually do. Even more, as the names are obvious in a random number context. It's quite nit-picky from you to call such a clarification nit-picky. – too honest for this site Mar 25 '16 at 23:33
  • Multi-dup, not that it will deter the rep-PersonalServicesWorkers :( – Martin James Mar 25 '16 at 23:43

2 Answers2

3

This is due to the fast processing of your code. What srandom does is resetting seed of random number generator. If you call it within a function it will get updated with the current time any time you call a function. Computations are so fast that the same time is retrieved on every call and thus the same number is being generated as the first number of sequence for a given seed.

bottaio
  • 4,963
  • 3
  • 19
  • 43
  • It gets called only once so the seed is not reset to the same value. – bottaio Mar 25 '16 at 22:50
  • Think of it as initializing sequence of consecutive integers with 0. If you init it once you'll get 0, 1, 2, 3 and so on. If you reset it every time to 0 you'll get 0, 0, 0... – bottaio Mar 25 '16 at 22:50
  • How does that change things when it is in the main function? (Sorry I repeated my question) – Arshitha Mar 25 '16 at 22:52
3

Putting it in sep_gen means you reseed every time sep_gen is called, not once per program run. And time is returning seconds since the epoch; your program is likely to call sep_gen all three times in the same second, so you're reseeding to a fixed start point before each random call.

Basically, as a rule, a program should only seed its random source once, or if it needs to reseed for whatever reason, needs to ensure it doesn't use a seed source that doesn't change enough. A really simple approach to reseeding without repeating yourself would be something like srandom(time(NULL) ^ random()); so the existing state of the generator perturbs the insufficiently varying external seed source, time(). This is only a toy example (constantly perturbing with time doesn't make huge changes to the expected behavior), just a note on how you might do something like this in more complex scenarios.

ShadowRanger
  • 143,180
  • 12
  • 188
  • 271
  • Could you please elaborate on the reseeding approach? How does 'srandom(time(NULL)^random());' work? Also, what did you mean when you said it wouldn't make huge changes to the expected behavior? Apologies, I'm a beginner so I didn't follow that part. – Arshitha Mar 25 '16 at 23:07
  • @ArshithaBasavaraj: It's calling `random` to pull a value from the existing stream of random and bitwise exclusive or-ing with the `time`. So the seed has two sources of "randomness", whatever went into the last seeding, and how many times random was drawn since then (though in this case, it's reseeded every time), plus the `time` output. Bitwise xor means the two values toggle each other's bits, combining usefully. It wouldn't change behavior much because most of the time, the `random` stream would be predictable; if you know the time the program launched, you can reproduce the random stream. – ShadowRanger Mar 25 '16 at 23:18