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.
Random. Next generates a random number whose value ranges from 0 to less than Int32. MaxValue. To generate a random number whose value ranges from 0 to some other positive number, use the Random.
The value of this constant is 2,147,483,647; that is, hexadecimal 0x7FFFFFFF.
The MinValue property or Field of Int32 Struct is used to represent the minimum possible value of Int32. The value of this field is constant means that a user cannot change the value of this field. The value of this field is -2,147,483,648. Its hexadecimal value is 0x80000000.
The internal implementation of Random.Next(int minValue, int maxValue)
generates two samples for large ranges, like the range between Int32.MinValue
and Int32.MaxValue
. For the NextInclusive
method I had to use another large range Next
, totaling four samples. So the performance should be comparable with the version that fills a buffer with 4 bytes (one sample per byte).
public static class RandomExtensions { public static int NextInclusive(this Random random, int minValue, int maxValue) { if (maxValue == Int32.MaxValue) { if (minValue == Int32.MinValue) { var value1 = random.Next(Int32.MinValue, Int32.MaxValue); var value2 = random.Next(Int32.MinValue, Int32.MaxValue); return value1 < value2 ? value1 : value1 + 1; } return random.Next(minValue - 1, Int32.MaxValue) + 1; } return random.Next(minValue, maxValue + 1); } }
Some results:
new Random(0).NextInclusive(int.MaxValue - 1, int.MaxValue); // returns int.MaxValue new Random(1).NextInclusive(int.MaxValue - 1, int.MaxValue); // returns int.MaxValue - 1 new Random(0).NextInclusive(int.MinValue, int.MinValue + 1); // returns int.MinValue + 1 new Random(1).NextInclusive(int.MinValue, int.MinValue + 1); // returns int.MinValue new Random(24917099).NextInclusive(int.MinValue, int.MaxValue); // returns int.MinValue var random = new Random(784288084); random.NextInclusive(int.MinValue, int.MaxValue); random.NextInclusive(int.MinValue, int.MaxValue); // returns int.MaxValue
Update: My implementation has mediocre performance for the largest possible range (Int32.MinValue
- Int32.MaxValue
), so I came up with a new one that is 4 times faster. It produces around 22,000,000 random numbers per second in my machine. I don't think that it can get any faster than that.
public static int NextInclusive(this Random random, int minValue, int maxValue) { if (maxValue == Int32.MaxValue) { if (minValue == Int32.MinValue) { var value1 = random.Next() % 0x10000; var value2 = random.Next() % 0x10000; return (value1 << 16) | value2; } return random.Next(minValue - 1, Int32.MaxValue) + 1; } return random.Next(minValue, maxValue + 1); }
Some results:
new Random(0).NextInclusive(int.MaxValue - 1, int.MaxValue); // = int.MaxValue new Random(1).NextInclusive(int.MaxValue - 1, int.MaxValue); // = int.MaxValue - 1 new Random(0).NextInclusive(int.MinValue, int.MinValue + 1); // = int.MinValue + 1 new Random(1).NextInclusive(int.MinValue, int.MinValue + 1); // = int.MinValue new Random(1655705829).NextInclusive(int.MinValue, int.MaxValue); // = int.MaxValue var random = new Random(1704364573); random.NextInclusive(int.MinValue, int.MaxValue); random.NextInclusive(int.MinValue, int.MaxValue); random.NextInclusive(int.MinValue, int.MaxValue); // = int.MinValue
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With