Random number between int.MinValue and int.MaxValu

2020-07-02 08:27发布

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.

标签: c# .net random
14条回答
Bombasti
2楼-- · 2020-07-02 09:16

As I understand it you want Random to put out a value between -2.147.483.648 and +2.147.483.647. But the problem is that Random given those values will only give values from -2.147.483.648 to +2.147.483.646, as the maximum is exclusive.

Option 0: Take the thing away and learn to do without it

Douglas Adams was not a Programmer AFAIK, but he has some good advice for us: "The technology involved in making anything invisible is so infinitely complex that nine hundred and ninety-nine billion, nine hundred and ninety-nine million, nine hundred and ninety-nine thousand, nine hundred and ninety-nine times out of a trillion it is much simpler and more effective just to take the thing away and do without it."

This might be such a case.

Option 1: We need a bigger Random!

Random.Next() uses Int32 as Argument. One option I can think off would be to use a different Random Function Which can take the next higher level of Integers (Int64) as input. An Int32 is implicitly cast into an Int64. Int64 Number = Int64(Int32.MaxValue)+1;

But afaik, you would have to go outside of .NET libraries to do this. At that point, you might as well look for a Random that is inclusive of the Max.

But I think there is a mathematical reason it had to exclude one value.

Option 2: Roll more

Another way is to use two calls of Random - each for one half of the range - and then add them.

Number1 = rng.Next(-2.147.483.648, 0);
Number2 = rng.Next(0, 2.147.483.647);
resut = Number1 + Number2;

However, I am 90% certain that will ruin the random distribution. My P&P RPG experience gave me some experience with dice chances and I know for a fact rolling 2 dice (or the same 2 times) will get you a very different result distribution than one specific die. If you do not need this random distribution, that is an option. But if you do not care too much about the distribution it is worth a check.

Option 3: Do you need the full range? Or do you just care for min and max to be in it?

I assume you are doing some form of testing and you need both Int.MaxValue and Int.MinValue to be in the range. But do you need every value in between as well, or could you do without one of them? If you have to lose value, would you prefer loosing 4 rather then Int.MaxValue?

Number = rng.Next(Int.MinValue, Int.MaxValue);
if(Number > 3)
  Number = Number +1;

code like this would get you every number between MinValue and MaxValue, except 4. But in most cases code that can deal with 3 and 5 can also deal with 4. There is no need to explicitly test 4.

Of course, that assumes 4 is not some important test number that has to be run (I avoided 1 and 0 for those reasons). You could also decide the number to "skip" Randomly:

skipAbleNumber = rng.Next(Int.MinValue +1, Int.MaxValue);

And then use > skipAbleNumber rather than > 4.

查看更多
啃猪蹄的小仙女
3楼-- · 2020-07-02 09:16

What about this?

using System;

public class Example
{
   public static void Main()
   {
      Random rnd = new Random();
      int min_value = max_value;
      int max_value = min_value;
      Console.WriteLine("\n20 random integers from 10 to 20:");
      for (int ctr = 1; ctr <= 20; ctr++) 
      {
         Console.Write("{0,6}", rnd.Next(min_value, max_value));
         if (ctr % 5 == 0) Console.WriteLine();
      }
   }
}
查看更多
登录 后发表回答