So, I've been nuts on this.
rand() % 6 will always produce a result between 0-5.
However when I need between, let's say 6-12.
Should I have rand() % 6 + 6
0+6 = 6.
1+6 = 7.
...
5+6 = 11. ???
So do I need to + 7 If I want the interval 6-12? But then, 0+7 =7. When will it randomize 6?
What am I missing here? Which one is the correct way to have a randomized number between 6 and 12? And why? It seems like I am missing something here.
If C++11 is an option then you should use the random header and uniform_int_distrubution. As James pointed out in the comments using rand and
%
has a lot of issues including a biased distribution:if you have to use rand then this should do:
Update
A better method using
rand
would be as follows:I obtained this from the C FAQ and it is explained How can I get random integers in a certain range? question.
Update 2
Boost is also an option:
There are a couple of concepts here.
First, there's the range:
[
denotes inclusive.)
denotes exclusive.The modulus operator % n produces
[0,n)
- 0,..n-1When you add a value to that result, you're adding the same value to both ends of the ranges:
%n + 6 = [n,n+6)
Now, if n is 6, as it in in your case, your output will be
[0,6)
%6 + 6 = [6,12)
Now what you want is
[6,13)
Subtract 6 from that:
[0,7) + 6 => n%7 + 6
Second, there is the matter of using rand(). It depends on whether you really care if your data is random or not. If you do really care that it is random, I highly suggest watching Stefan T Lavalej's talk on the pitfalls of using rand() at Going Native 2013 this year. He also goes into what you should use.
If the randomness of rand() doesn't matter to you, then by all means use it.
The modulus operation
a % b
computes the remainder of the divisiona / b
. Obviously the remainder of a division must be less thanb
and ifa
is a random positive integer thena%b
is a random integer in the range 0 .. (b-1)In the comments you mention:
This algorithm produces values in the half-open range [min, max). (That is, max is outside the range, and simply denotes the boundary. Since we're talking about ranges of integers this range is equivalent to the closed range [min, max-1].)
When you write '0 - 5' or '6 - 12' those are closed ranges. To use the above equation you have to use the values that denote the equivalent half open range: [0, 6) or [6, 13).
Note that
rand() % (max-min) + min
is just a generalization of the rule you've apparently already learned: thatrand() % n
produces values in the range 0 - (n-1). The equivalent half-open range is [0, n), andrand() % n
==rand() % (n-0) + 0
.So the lesson is: don't confuse half-open ranges for closed ranges.
A second lesson is that this shows another way in which
<random>
is easier to use thanrand()
and manually computing your own distributions. The built-inuniform_int_distribution
allows you to directly state the desired, inclusive range. If you want the range 0 - 5 you sayuniform_int_distibution<>(0, 5)
, and if you want the range 6 - 12 then you sayuniform_int_distribution<>(6, 12)
.rand()%7+6
is more terse, but that doesn't mean it is easier to use.You need rand() % 7 + 6.
Lowest number from rand() %7: 0. Highest number from rand() %7: 6.
0 + 6 = 6. 6 + 6 = 12.