I am writing a method that will generate an unsigned int between 1 and 6 (boundaries included). The current method I have is below.
private static Random random = new Random();
...
private static uint GetRandomChannel()
{
return Convert.ToUInt32(random.Next(1, 6));
}
I've run this method a thousand times and I get numbers 1 through 5 but never get 6. Why is this happening and how can I fix it?
The second parameter to random.Next()
is an exclusive upper bound.
Parameters
minValue: The inclusive lower bound of the random number returned.
maxValue: The exclusive upper bound of the random number returned. maxValue must
be greater than or equal to minValue.
Return value
A 32-bit signed integer greater than or equal to minValue and less than maxValue; that is, the range of return values includes minValue but not maxValue. If minValue equals maxValue, minValue is returned.
This means that random.Next(1, 6)
will only return values n
in the range 1 <= n < 6
.
So for your die rolling simulation you will need to use
random.Next(1, 7)
Note: The design of this API is odd. It has special case handling for minValue == maxValue
which seems to needlessly complicate the API. If I had designed this API I would have made both parameters be inclusive limits. This would have resulted in a pleasing symmetry and would have allowed random numbers that cover the full range of int
.
According to MSDN, the upper bound is exclusive, while the lower bound is inclusive.
Random.Next Method (Int32, Int32)
So your code shoudl be:
return Convert.ToUInt32(random.Next(1, 7));
According to the MSDN documentation here, the random.Next
function returns a value strictly less than MaxValue
(6 in your case).
You can't "fix" this; it's just what this method means to do:
A 32-bit signed integer greater than or equal to zero and less than
MaxValue.
So if you want to generate a random integer in [a, b], you need to use .Next(a, 1 + b)
.
According to the method documentation, the lower bound is inclusive and the upper bound is exclusive. That means that random.Next(lower, upper) will return the lower number, but it is guaranteed to never return the upper one.