Here's a bit of a puzzler: Random.Next()
has an overload that accepts a minimum value and a maximum value. This overload returns a number that is greater than or equal to the minimum value (inclusive) and less than the maximum value (exclusive).
I would like to include the entire range including the maximum value. In some cases, I could accomplish this by just adding one to the maximum value. But in this case, the maximum value can be int.MaxValue
, and adding one to this would not accomplish what I want.
So does anyone know a good trick to get a random number from int.MinValue
to int.MaxValue
, inclusively?
UPDATE:
Note that the lower range can be int.MinValue
but can also be something else. If I know it would always be int.MinValue
then the problem would be simpler.
Well, I have a trick. I'm not sure I'd describe it as a "good trick", but I feel like it might work.
So, basically an extension method that will simply generate four bytes if the upper-bound is
int.MaxValue
and convert to anint
, otherwise just use the standardNext(int, int)
overload.Note that if
maxValue
isint.MaxValue
it will ignoreminValue
. Guess I didn't account for that...You can not use
Random.Next()
to achieve what you want, because you can not correspond sequence ofN
numbers toN+1
and not miss one :). Period.But you can use
Random.NextDouble()
, which returns double result:0 <= x < 1
aka[0, 1)
between 0, where[
is inclusive sign and)
exclusiveHow do we correspond N numbers to [0, 1)? You need to split
[0, 1)
to N equal segments:[0, 1/N)
,[1/N, 2/N)
, ...[N-1/N, 1)
And here is where it becomes important that one border is inclusive and another is exclusive - all N segments are absolutely equal!
Here is my code: I made it as a simple console program.
You can add
1
to generated number randomly so it still random and cover full range integer.No casting, no
long
, all boundary cases taken into account, best performance.This method can give you a random integer within any integer limits. If the maximum limit is less than int.MaxValue, then it uses the ordinary Random.Next(Int32, Int32) but with adding 1 to upper limit to include its value. If not but with lower limit greater than int.MinValue, it lowers the lower limit with 1 to shift the range 1 less that add 1 to the result. Finally, if both limits are int.MinValue and int.MaxValue, it generates a random integer 'a' that is either 0 or 1 with 50% probability of each, then it generates two other integers, the first is between int.MinValue and -1 inclusive, 2147483648 values, and the second is between 0 and int.MaxValue inclusive , 2147483648 values also, and using them with the value of 'a' it select an integer with totally equal probability.
This is guaranteed to work with negative and non-negative values: