33

I'm trying to generate a random int that is either 0 or 1 in C++. Right now, I receive a 0 every time I run this code, and I'm not sure why. What's the problem here?

#include <ctime>
#include <cstdlib>

srand(time(0));
int randomval = rand() % 2;
cout << randomval << endl;
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
Rich Byden
  • 509
  • 2
  • 6
  • 13

8 Answers8

218

It is called bad luck. Try it again.

Michael Krelin - hacker
  • 138,757
  • 24
  • 193
  • 173
28

I know this is an older question but I believe this answers the question properly.

Don't re-seed the the generator every time you run that code.

By seeding it to the same value every time, you're just gonna get the same "random" number. Remember this is a Pseudo-Random number generator, so based on the seed value, a "random" number will be generated. So if you seed it with the same number every time you're just gonna get the same number every time.

The solution is to call srand(time(NULL)) only once in your program execution. Then, each call to rand() will give you a different number every time.

Christian Gossain
  • 5,942
  • 12
  • 53
  • 85
4

On theory, there's 50% chance you get 0, and 50 - 1. You may want to try with different modulo - for example 100, to check if this works. And I'm sure it does.

You have just ran this code a few times, not enough.

Other idea to test it:

srand(time(0));
for( int i = 0; i < 1000000; ++i )
{
    assert( 0 == ( rand() % 2 ) );
}
Kiril Kirov
  • 37,467
  • 22
  • 115
  • 187
2

I would like to add that when you use srand(time(0)); the "random number" will always be the same in the same second. When I tried to run your program 10000 times and group it by uniq I saw that the number would not change within a second.

for i in `seq 1 10000`; do ./a.out; done | uniq -c
    693 0
   3415 1
    675 0
    673 1
    665 0
    674 1
    668 0
    711 1
    694 0
    673 1
    459 0
toftis
  • 1,070
  • 9
  • 26
2
bool random() {
    if (rand() % 2 == 0)
        return true;
    else return false;
}
  • 2
    Why are you testing and then returning what you have tested. Remember, if your if only has `return true` and your else only has `return false`, it is always better to just return what you are testing. i.e. `return rand() % 2 == 0;` – v010dya Apr 25 '20 at 06:10
0

Call srand(time(NULL)); just once.

Then use a loop like this, you will always get a 0 or 1 this way.

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

srand(time(NULL));

for (i=0;i<10;i++)
{
    printf("%d\n",rand() % 2);
    i++;
}

return 0;
Tom
  • 3,031
  • 1
  • 25
  • 33
Azy
  • 11
0

Although your code suggests that you want to receive them equally likely, you didn't state that, and perhaps you have simply thought that it was impossible to do otherwise. If you want a different distribution, and you are willing to rewrite your code (and make it C++11 compliant), you can do the following:

    const double chance = 0.3; // this is the chance of getting true, between 0 and 1;
    std::random_device rd;
    std::mt19937 mt(rd());
    std::bernoulli_distribution dist(chance);
    bool result = dist(mt);

If you will need to do that in a loop, only repeat the last statement dist(mt), keep all the generated objects as they are without recreating them.

v010dya
  • 5,296
  • 7
  • 28
  • 48
-2

You are not checking against anything. Use:

#include <ctime>
#include <cstdlib>

srand(time(0));
int randomval = rand() % 2 == 0;
cout << randomval << endl;
DJ LW
  • 1
  • 3