2

I am writing a simple C program that tosses a coin 100000 times and calculates how many heads and how many tails resulted from the toss using srand and rand. Here is what I have:

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

int main(void){

    int i;
    int h=0;
    int t=0;
    int n;

    for(i=0;i<100000;i++){
        srand(time(NULL));
        n=rand()%2;
        if(n==0){
            h++;
        }
        else {   
            t++;
        }
    }

    printf("%d heads\n", h);
    printf("%d tails\n", t);

    return EXIT_SUCCESS;
}

However when running the program I sometimes get 100000 heads and 0 tails and sometimes 0 heads and 100000 tails and sometimes I get random numbers in heads and tails but not in any way a 50% heads 50% tails.

Am I missing something? Thanks!

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
MinaHany
  • 1,015
  • 4
  • 16
  • 32

8 Answers8

7

You are seeding the pseudo-random number generator with the same seed each time around the look. Simply move the call to srand outside the loop.

srand(time(NULL));
for(i=0;i<100000;i++){
    n=rand()%2;
    .....

A pseudo-random number generator (PRNG) is deterministic. That is, given the same initial seed, it will return the same sequence of numbers each time is is called. In your code, since you seed every time you call rand, you get the same sequence of 1 number for every iteration of your loop. Now, different executions of the program will have different results, because time will have changed.

And in the cases when you were not seeing 100% heads or 100% tails, that would be when the loop took sufficiently long for time to have advanced.

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • Thanks for your answer, however can you explain a bit why does this happen? I thought that having the srand outside the loop would only seed the number generator once during the execution of the whole loop. – MinaHany Mar 13 '12 at 14:48
  • @user1249740 You only want it to be seeded once. I've added some explanation to the answer. – David Heffernan Mar 13 '12 at 14:50
  • This is correct - I would add to the explanation that the variability observed in the results comes from the speed at which the code executes and the resolution of the time() function. The code is executed so fast that many iterations receive the same "tick" value from the system time as a seed to the PRNG –  Mar 13 '12 at 14:52
  • @sgorozco Yes, that's what I was trying to convey in the final paragraph. – David Heffernan Mar 13 '12 at 14:53
  • @DavidHeffernan sorry, I think I missed your last paragraph. –  Mar 13 '12 at 17:51
2

Yes, if you are using srand, it's getting a number randomly using time, so if you or the computer chooses a value randomly in less than a second, the number will come out to be the same number every time.

dzamudio1
  • 21
  • 1
  • 1
    It's good to also mention explicitly that srand is typically only called once at the beginning of a program – Bogatyr Oct 17 '12 at 21:53
1

I think the problem is calling srand() for every iteration; you only need to call it once.

Try this version:

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

int main(void){


int i;
int h=0;
int t=0;
int n;

srand(time(NULL));
for(i=0;i<100000;i++){
    if((rand() & 1) == 1){
        h++;
    }
    else{
        t++;
    }
}

printf("%d heads\n", h);
printf("%d tails\n", t);

return EXIT_SUCCESS;
}

This gives fairly consistent results:

$ ./rand
49980 heads
50020 tails
$ ./rand
50131 heads
49869 tails
$ ./rand
50000 heads
50000 tails
$ ./rand
50000 heads
50000 tails
$ ./rand
50093 heads
49907 tails
$ ./rand
50093 heads
49907 tails

EDIT: Stratch my previous comment about rand() - it doesn't return negative values.

trojanfoe
  • 120,358
  • 21
  • 212
  • 242
  • http://www.cplusplus.com/reference/clibrary/cstdlib/rand/ - rand() won't return values below 0. – Pawel Zubrycki Mar 13 '12 at 14:47
  • 1
    @PawelZubrycki yeah I did a quick `man rand`, saw it returned a (signed) `int` and decided it can return negative, confusing it with the Java `Random.nextInt()` which can return negative. The `& 1` must be quicker than a modulo. – trojanfoe Mar 13 '12 at 14:56
0

Don't call srand within your loop. It should be called only once, at the very beginning of execution, if you're going to invoke it at all.

As it is, you're resetting the random number generator to the same seed (unless a second boundary passes) before each time you use it... so it should be no surprise when it comes up with consistent results!

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
0

you're using the identical seed value at each iteration of the loop.

move srand(time(NULL)); to before the for loop.

jglouie
  • 12,523
  • 6
  • 48
  • 65
0

Yeah. It's all about this line:

srand(time(NULL));

Move it before for loop and it will be working. srand sets seed so if you call it like that and time(NULL) won't change (and it's quite possible) rand() will always return the same value.

Pawel Zubrycki
  • 2,703
  • 17
  • 26
0

Duplicate to srand(time(NULL)) doesn't change seed value quick enough. And yes, as said above, move

srand(time(NULL)); 

outside(before ;)) the loop :)

Community
  • 1
  • 1
instanceOfObject
  • 2,936
  • 5
  • 49
  • 85
0

Put srand outside for loop. Call srand(time(null) all only one time.

Bacardi
  • 13
  • 1
  • 1
  • 4