How Does C++ Handle Random Number Generation in Coin Toss Simulations?

Click For Summary

Discussion Overview

The discussion focuses on the implementation of random number generation in C++ for simulating coin tosses. Participants explore the behavior of the pseudo-random number generator, particularly the effects of seeding and the placement of the seeding function within the code.

Discussion Character

  • Technical explanation
  • Conceptual clarification
  • Debate/contested

Main Points Raised

  • One participant shares a code snippet for simulating coin tosses and questions why placing the randomization inside the function results in repeated outcomes.
  • Another participant explains that initializing the pseudo-random number generator with the same seed leads to the same sequence of numbers, especially when the loop runs quickly.
  • A participant notes that the value of time(0) remains constant across iterations, leading to confusion about the differing results when seeding is done inside versus outside the loop.
  • Further clarification is provided on how the placement of the srand(seeder) statement affects the generation of random numbers, emphasizing that it resets the sequence each time it is called.
  • Participants express surprise at the deterministic nature of pseudo-random number generators and discuss the implications of this for their simulations.
  • One participant shares an observation of patterns in the outcomes based on the number of tosses, suggesting a potential coincidence rather than a systematic issue.
  • A later reply recommends using C++11's built-in random number generators for better randomness and provides an alternative code example using the Mersenne-Twister algorithm.

Areas of Agreement / Disagreement

Participants generally agree on the deterministic nature of pseudo-random number generators and the importance of proper seeding. However, there is some disagreement regarding the implications of observed patterns in the outcomes of the coin toss simulations, with no consensus on whether these patterns indicate a flaw in the random number generation process.

Contextual Notes

Participants note that the behavior of the rand() function may not be suitable for scientific purposes or cryptography, highlighting limitations in the randomness provided by traditional methods.

Lord Anoobis
Messages
131
Reaction score
22
Homework Statement
Write a function named coinToss that simulates the tossing of a coin and generates the number of tosses as input by the user.
Relevant Equations
None.
The program works as intended.
C++:
#include <iostream>
#include <ctime>
#include <cstdlib>

int coinToss ();int main ()
{
    int tosses, result;
    std::count << "How many coin tosses? ";
    std::cin >> tosses;
    size_t seeder = time(0);
    srand(seeder);
    
    for (int i = 0; i < tosses; i++)
    {
        result = coinToss ();
        std::count << result << "\n";
    }
    
    return 0;
}

int coinToss ()
{
    int toss;
    toss = rand() % 2 + 1;
    return toss;
}

What I would like to know is why when the randomization is placed within the function (which is what I had done first) does it spit out either all 1s or all 2s?
C++:
int coinToss ()
{
    int toss;
    size_t seeder = time(0);
    srand(seeder);
    toss = rand() % 2 + 1;
    return toss;
}
 
Physics news on Phys.org
When you initialize the pseudo-random number generator with the srand(seeder) statement, this starts off a new sequence of pseudo-random numbers. For the same value of seeder, you will always get the same sequence of numbers. The loop runs so fast, that the value of time(0) is always the same each time through the loop. I think the value of time(0) is in milliseconds, but I'm not sure. So you always intialize with the same value of seeder, so the rand() statement always gives you the same number. Try printing out the value of time(0).

Edit: Actually the value of time(0) is in seconds since 00:00 hours, Jan 1, 1970 UTC, so the loop can run many,many times in 1 second.
 
Last edited:
Tried that just now. The value of time(0) stays the same in both cases but with different results. As long as seeder and its accomplices are part of the function its always 1s or 2s. Weird.
 
It's not weird, it's completely understandable. What part of my explanation didn't you get?
 
phyzguy said:
It's not weird, it's completely understandable. What part of my explanation didn't you get?
I'm not quite sure why the two cases behave so differently if the value of time(0) does not change for each repetition of the loop in both cases.
 
In the case where the srand(seeder) statement is outside the loop, you get:

Initialize pseudo-random number generator
Pseudo-random number 1
Pseudo-random number 2
Pseudo-random number 3
...

In the case where the srand(seeder) statement is inside the loop, you get:

Initialize pseudo-random number generator
Pseudo-random number 1
Initialize pseudo-random number generator
Pseudo-random number 1
Initialize pseudo-random number generator
Pseudo-random number 1
...
 
I just had it generate randoms only. I was under the impression that in the case of it being in the loop it would generate a different number on each pass regardless.
 
Lord Anoobis said:
I just had it generate randoms only. I was under the impression that in that case it would generate a different number on each pass regardless.
No! It's a pseudo-random number generator. You should read about how they work. It is deterministic. For the same seed value, it will always generate the same sequence of numbers.
 
phyzguy said:
No! It's a pseudo-random number generator. You should read about how they work. It is deterministic. For the same seed value, it will always generate the same sequence of numbers.
Yeah, I can see now what you meant in the first post. Valuable lesson learned and thanks.
 
  • #10
On another note, when I was testing it earlier today multiple times, an even number of tosses always gave 2s and an uneven number 1s, from 1 all the way to 20 and on more than one attempt. It was only when I used say, 10, a number of times in succession that it eventually broke formation. If ever there was a case of coincidence further confounding the issue.
 
  • #11
Since you already start doubting your random number generation: I do not know about your specific observation, but rand() is generally not an appropriate way to generate random numbers. Not for scientific purposes. Absolutely not for cryptography. Probably not even for computer games with dice rolling.

Since version C++11, C++ features proper random number generators out of the box. I highly recommend using them for all cases (except cryptography - just don't do cryptography at all). The Mersenne-Twister algorithm is a good default. Here's your code using this RNG, instead:
C++:
#include <ctime>
#include <iostream>
#include <random>// Mersenne-Twister generator with current time as seed.
std::mt19937 randomNumberGenerator(time(0));

// Distribution represeting a coin: Gets 1 or 2,
// depending on the random number passed.
std::uniform_int_distribution<> coinDistribution(1, 2);int coinToss() {
    return coinDistribution(randomNumberGenerator);
}int main() {
    int tosses, result;
    std::count << "How many coin tosses? ";
    std::cin >> tosses;

    for (int i = 0; i < tosses; i++) {
        result = coinToss();
        std::count << result << "\n";
    }

    return 0;
}
 

Similar threads

  • · Replies 4 ·
Replies
4
Views
2K
  • · Replies 3 ·
Replies
3
Views
1K
  • · Replies 15 ·
Replies
15
Views
2K
  • · Replies 2 ·
Replies
2
Views
3K
  • · Replies 3 ·
Replies
3
Views
2K
Replies
8
Views
2K
  • · Replies 24 ·
Replies
24
Views
2K
  • · Replies 7 ·
Replies
7
Views
2K
  • · Replies 23 ·
Replies
23
Views
9K
  • · Replies 2 ·
Replies
2
Views
2K