views:

937

answers:

11

Hi, I was wondering if there is a smart way to find out

There is a 1/4 chance something happens.

I know we can do this with rand() % 4 and checking if it is equal to 0, but is there a way without using rand()? In c++, thanks.

+4  A: 
Greg Hewgill
awesome answer :D
Johannes Schaub - litb
Awesome, but useless in answering the question :-) It can never give a 25% chance of probability, only 0 or 100% (unless you check the return value against rand()%4 ...
paxdiablo
Unfortunately this is not a useful answer. People shouldn't up vote answers in a non-subjective thread just because it's funny.
spoon16
This was not helpful, but funny. (Please click the "Funny" button)
Mark Stock
I think ppl upvoted this because it's a funny answer to a funny question.
Johannes Schaub - litb
+3  A: 

You could write your own rand. ( dont do it ).
You could grab the tickcount. ( dont do it too often ).
You could just count, and every fourth call return true.

You should probably just call rand().

Sanjaya R
A: 

Umm... write your own rand()? You will need some kind of random function!

Vilx-
+1  A: 

Why not use rand()? If you are concerned about "true" randomness vs. pseudo randomness, you can try using physical sources of random bits. Much more complicated, and usually unnecessary.

Yuval F
No physical method of generating random bits is certified by NIST for use in FIPS-140-2 compliant devices. Only pseudorandom techniques are acceptable (see Annex C).
Peter K.
+10  A: 

If you mean you want to avoid the inherent crappiness of many rand() implementations, you should probably look into the Boost Random library, which has several high-quality pRNGs (pseudo-random number generators), and many ways to control the output. This library is also present in slightly modified form in std::tr1.

coppro
I would like to see just ONE question about C++ that isn't answered with "Use boost:;something_or_other" :-)
paxdiablo
There's a good reason they all are answered by boost!
coppro
+4  A: 
rand() < RAND_MAX/n;

pick a better rand() than C's if you don't like C's standard rand().

BCS
+8  A: 

Never ever use % for truncating a PRNG value into a range. Most PRNGs have relatively non-random lower order bits.

For your case, use a division (RAND_MAX / n) like BCS suggests.

Barry Kelly
@Barry Kelly: thanks for mentioning. I always used to use the `%`.
Lazer
In fact, there's a common implementation of `rand()` that alternates between even and odd numbers!
dan04
+1  A: 

You could use another type of RNG such as the Mersenne twister which has better overall entropy. I also hear good thing about Multuply with Carry RNGs.

Evan Teran
A: 

Try:

static int r = 0;
: : :
if ((r = (r+1)%4) == 0) {
    // do something.
}

Then you'll find it gives you a perfect 25% probability of something happening (assuming you execute the if-statement a multiple of four times.

</humor>

paxdiablo
+2  A: 

I don't know much C++, so I might be wrong. But it seems rand() return a value between 0 and RAND_MAX. So maybe you could do something like this:

double odds = .25;

if(rand() <= RAND_MAX * odds) {
    // there should be .25 chance of entering this condition
}

PS: Maybe this requires some casting.

Juan Pablo Califano
Assuming that when he says "1/4" chance he means "1 in 4" or 25%. He might also mean "1 to 4" which is 20%.
John Dibling
+1  A: 

4 is a special case. You can assume that your PRNG has got 50% chances of outputting an even number, which is the case - I think - for the LCG of the libc (rand). The probability of outputting an even number twice is therefore 25%.

Therefore...

bool rand_afourth(void)
{
    return !!((rand() & 1) & (rand() & 1));
}

And now for the pedantic...

What you want to do is to have an uniform random generated, but restricted to a certain range, in this case an entropy of 4. If your PRNG has, say, an entropy of 32-bit, you cannot be certain that computing the output mod 4 will work as expected. This require a bit more work.

Fortunately, this work has already been implemented in the boost library.

boost::uniform_int<> aFourth(1,4)

And you would for example say "ok" everytime you get 1 (or 2, 3, 4, as you fancy).

But you may not want to use the boost library. Then, simply look at the code of uniform_int and reproduce the behaviour. Talents imitate, geniuses steal. ;)

Edouard A.
Any random number generator should generate even values 50% of the time, otherwise it's not random. That being said, the low bits of PRNGs are notoriously predictable, so your method is likely worse than simple rand() % 4 == 0, for randomness, and is definitely slower and less understable.
Eclipse
Which PRNG are you talking about? All the bits of the libc rand() function are predictable if you have any element of the sequence. If the low bits of your PRNG have special properties, this means your PRNG is problematic in the first place.Maybe I didn't understand your comment?
Edouard A.
See Barry Kelly's answer above.
Eclipse