可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
At the following: http://www.fredosaurus.com/notes-cpp/misc/random.html
It mentions that if we want to generate a random number in the range 1-10
, we can do the following:
r = (rand() % 10) + 1;
Why do we add 1
? Can you just explain how the process works?
And, regarding initializing the random number generator, it mentioned doing the following:
srand(time(0));
Can you explain this process? And, what happens if we don't initialize at all?
Thanks.
回答1:
You add 1, because you want random number 1-10, not 0-9, what will %
do without the +1
.
For example, 10 % 10 == 0
and 9 % 10 == 9
, so this gives you 0-9.
Adding +1
will "move" this interval to 1-10-> 10 % 10 + 1 == 1
and 9 % 10 + 1 == 10
EDIT: Sorry, forgot about you srand
question.
rand()
generates the same sequence of numbers, unless you call srand
and "seed" the random number generator with different value, before calling rand()
. So, here time(0)
seeds the random number generator with the current time, that gives you different value for all the times, you call rand()
回答2:
rand()
returns an int
in the range [0, RAND_MAX
]. rand() % 10
returns an int
in the range [0,9] because non-negative x modulo k is at most k-1. Adding 1 shifts the range to [1,10].
(The results from rand() % k
are not guaranteed to be uniformly distributed. Even if you patch that up, this is really a poor man's way of generating random numbers and not recommended for generating crypto keys and the like. A stronger RNG library is part of Boost.)
srand(time(0))
takes the current time in the hope that the user executes the program at random times. If the program is executed at time t and t + 1s, the random number generator will make sure it returns very different results. If you don't seed it, you're likely to get the same results every time. I'm not sure what the C standard has to say about this, though. In any case, if you seed once in an application that runs for a long time, rand()
eventually starts repeating itself.
(This in turn is the poor man's way of seeding the RNG. On Linux or BSD, read from the special file /dev/random
to get "real" random seeds. Alternatively, check if your operating system can return the time with at least microsecond granularity.)
回答3:
When you perform "modulo" arithmetic you get the remainder when dividing. So rand()
gives you an integer and rand() % 10
is a number between 0 and 9. Add 1 to get a number in the range 1 to 10
Random number generators will always generate the same sequence of numbers unless you seed them first. srand(time(0))
"seeds" the random generator with a number based upon the current time in seconds. The theory is that you will run this at different times thus seeding it differently each time, and thus you will get a different sequence of numbers each time the program is run.
回答4:
Why do we add 1?
When you divide a number by 10
, remainders will be between 0-9
. So, to change this we add 1.
回答5:
random without ++1 would make random number in range of 0-9 like array in C goes from 0 to n, same in here. Very first number is 0 so to get 1-10 you add minimal value (1).
回答6:
The modulo part is answered by others. You must initialize with srand(time(0)) because otherwise you will get the same series of random numbers each time your program runs.
As far as I understand it, this is because the generator starts with a certain number and following numbers are calculated based on this starting number.
You can initialise with any number you like, for example for testing you could use srand(0) and get the same numbers as in the last run. To get a fully random series you use time(0) because that initialises with the actual time in seconds Which is random enough for most purposes.
回答7:
Regarding the srand(), one item that I don't think has been explained - for a given seed, you will always get the same random sequence (not just srand(0)). Because the time(0) function is changes every second, it is not likely that the seed will be the same from run to run, which is why it is often used with srand().
Think of the random number generator as a complicated mathematical expression with a single input. Every time you call it, it uses the previous output as then input to generate the next number. The results are predictable, if your input is 5 and you get 10 one time, you'll get it the next time, too. So unless you want to use the same random sequence every run (sometimes not a bad thing!), you want to set the first input (the seed) to something (somewhat) random, such as the current time.
Caveat: random number generators internally use a much larger number than the one they output, so the input/output relationship is not usually as straightforward as the '5 gets you 10' in the example. But the idea is the same.