Why is (rand ()% nothing) always 0 in C ++?

I'm having trouble running rand () to work in C ++. Rand () usually gives me a very large amount. When I try to use modulo operator (%) to give it a range, it always returns 0, no matter what.

A visit to the random number generator at the beginning of the program also does not help.

+4
c ++ random
Jan 25 '10 at 1:31
source share
3 answers

The following code works just fine for me (emitting a random number between 0 enabled and 1000 excluded each time it starts):

#include <cstdlib> #include <ctime> #include <iostream> int main() { std::srand(time(0)); std::cout<<(std::rand() % 1000)<<std::endl; return 0; } 
+7
Jan 25 '10 at 1:40
source share

I think this is common if the random generator algorithm leaves a certain set of bits equal to zero. (For example, if the least significant bits are zero, the number of modes of some low constant will always be zero.)

Maybe you should try something like:

 const int desired_maximum = /* ... */; int r = (((double)rand()) / RAND_MAX) * desired_maximum; 

For example, this manpage link says:

In numerical recipes in C: The Art of Scientific Computing (William H. Press, Brian P. Flannery, Saul A. Teukulsky, William T. Wetterling, New York: Cambridge University Press, 1992 (2nd ed., P. 277) ), the following comments were made:

"If you want to generate a random integer from 1 to 10, you should always do this using the most significant bits, as in

  j = 1 + (int) (10.0 * (rand () / (RAND_MAX + 1.0))); 
and never reminiscent of anything
  j = 1 + (rand ()% 10); 
(which uses the least significant bits). "
+8
Jan 25 '10 at 1:42
source share

It seems that your immediate problem has been resolved, but I think another point is worth mentioning. Using the remainder to fix outputs from rand to a given range usually results in biased results. Specifically, if the range of the generator (RAND_MAX in the case of C or C ++) is not a multiple of the range you are clamping, some outputs will occur more often than others. For comparison, consider trying to split 11 candies evenly between 3 children (without breaking them into pieces). The only way to do this is to NOT hand out some sweets. Similarly, with a random number generator, the only way to get a uniform distribution in your output is not to use some inputs.

 int rand_lim(int limit) { /* return a random number between 0 and limit inclusive. */ int divisor = RAND_MAX/(limit+1); int retval; do { retval = rand() / divisor; } while (retval > limit); return retval; } 

As Aveikau noted in his post, you usually want to use the upper bits from a typical linear congruent generator. The lower bits are usually more predictable. Dividing, instead of taking the remainder, saves the upper bits. Although this has a while loop, it is often executed only once and rarely more than twice, so its impact on performance is pretty minimal.

Regardless of whether itโ€™s worth it, it depends on what kind of use you create from the number you create - if you want to play dice or cards for the game that your children will play a couple of times, using the rest, as a rule, it will hurt a thing. If you are trying to do some kind of Monte Carlo simulation (for example), you probably want to be a little more careful though ...

+4
Jan 25
source share



All Articles