Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Random number between int.MinValue and int.MaxValue, inclusive

Tags:

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.

like image 355
Jonathan Wood Avatar asked Jul 19 '19 19:07

Jonathan Wood


People also ask

Does random next include 0?

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.

What is the value of INT MaxValue?

The value of this constant is 2,147,483,647; that is, hexadecimal 0x7FFFFFFF.

What is int MinValue?

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.


1 Answers

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 
like image 163
Theodor Zoulias Avatar answered Sep 20 '22 16:09

Theodor Zoulias