Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Coin flip simulation never exceeding a streak of 15 heads

I was working on a simulation of the St Petersburg Paradox when I realized my coin-flipping code never recorded any streaks of greater than 15 heads in a row. I ran the simulation 100,000,000 times, which should have resulted in an average of 1526 streaks of heads 16 long.

(0.5^16) x 100,000,000 = 1526

Clearly, something is wrong.

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

int main(int argc, char const *argv[])
{
srand(time(0));

int i, lim = 100000000, streak = 0, maxstreak = 0;
for (i = 0; i < lim; ++i)
{
    if (rand()%2) {
        streak++;
        if (streak > maxstreak) maxstreak = streak;
    }
    else streak = 0;
}

printf("Ran %d times, longest streak of %d\n", lim, maxstreak);
return 0;
}

Returns the following every time:

Ran 100000000 times, longest streak of 15

Thanks for your help!

Edit: running GCC version 4.6.2 on Windows 7 x64. Bit new to programming in general.

Edit 2: thanks for everyone's help! Anyone sticking around, I wonder what about the current implementation would give a limit of 15 heads? How would the rand() function be so interestingly broken to produce this problem?

like image 481
tpixel Avatar asked Nov 06 '13 04:11

tpixel


People also ask

What are the odds of flipping heads 10 times in a row?

Junho: According to probability, there is a 1/1024 chance of getting 10 consecutive heads (in a run of 10 flips in a row). However, this does not mean that it will be exactly that number.

What are the odds of getting heads 9 times in a row?

There is a 38.7% chance of getting a heads 9 times in a row.

Do a coin flip 10 times?

If you flip a fair coin 10 times, you can get 0 heads about 0.1% of the time, 1 head about 1% of the time, 2 heads about 4% of the time, 3 heads about 12% of the time, 4 heads about 21% of the time, and 5 heads about 25% of the time. Thus, the chances of getting 5 heads is about 1 in 4.

How often a streak of six heads or a streak of six tails comes up in a randomly generated list of heads and tails?

The probability of getting six in a row is indeed ~1.56%.


1 Answers

Try choosing different seed values for your random number generator. Though rand() is a pretty good random number generator, it really is a pseudo-random number generator. You might want to read the man pages for rand (man -s3 rand), which clearly state that you should (for some implementations) use higher-order bits than the lower-order bits...

NOTES
   The versions of rand() and srand() in the Linux C Library use the  same
   random number generator as random(3) and srandom(3), so the lower-order
   bits should be as random as the higher-order bits.  However,  on  older
   rand()  implementations,  and  on  current implementations on different
   systems, the lower-order bits are much less  random  than  the  higher-
   order  bits.   Do  not use this function in applications intended to be
   portable when good randomness is needed.  (Use random(3) instead.)

Without knowing more about the system you are running your program on, we cannot know whether that is your problem. But try changing your code to use a different bit than the 2^0 bit.

Running your version works for me,

/coinflipsim 
Ran 100000000 times
head 50006650, streak 27
tail 49993350, streak 25

Here is code that works for me, using a different bit than bit 0,

int main(int argc, char const *argv[])
{
    srand(time(0));

    int i, lim = 100000000;
    int head=0, tail=0;
    int hstreak=0, tstreak=0;
    int hstreakmax=0, tstreakmax=0;
    for (i = 0; i < lim; ++i)
    {
        //if (rand()%2)
        if( rand() & (1<<13) ) //pick a bit, try different bits
        {
            head++;
            if( ++hstreak>hstreakmax) hstreakmax=hstreak;
            tstreak=0;
        }
        else {
            tail++;
            if( ++tstreak>tstreakmax) tstreakmax=tstreak;
            hstreak=0;
        }
    }
    printf("Ran %d times\n",lim);
    printf("head %d, streak %d\n",head,hstreakmax);
    printf("tail %d, streak %d\n",tail,tstreakmax);
    return 0;
}

Changing the rand()%2 line to this and rerun,

        if( rand() & (1<<13) ) //pick a bit, try different bits

Different results,

./coinflipsim 
Ran 100000000 times
head 50001852, streak 25
tail 49998148, streak 28
like image 167
ChuckCottrill Avatar answered Sep 23 '22 20:09

ChuckCottrill