C# int.MinValue和int.MaxValue(含)之间的随机数
这里有一个难题:C# int.MinValue和int.MaxValue(含)之间的随机数,c#,.net,random,C#,.net,Random,这里有一个难题:Random.Next()有一个重载,它接受最小值和最大值。此重载返回一个大于或等于最小值(包含)且小于最大值(排除)的数字 我想包括整个范围,包括最大值。在某些情况下,我可以通过在最大值上加一个来实现这一点。但在这种情况下,最大值可以是int.MaxValue,向其中添加一个值将无法实现我想要的效果 那么有人知道从int.MinValue到int.MaxValue获取随机数的好方法吗 更新: 请注意,较低的范围可以是int.MinValue,但也可以是其他范围。如果我知道它总是
Random.Next()
有一个重载,它接受最小值和最大值。此重载返回一个大于或等于最小值(包含)且小于最大值(排除)的数字
我想包括整个范围,包括最大值。在某些情况下,我可以通过在最大值上加一个来实现这一点。但在这种情况下,最大值可以是int.MaxValue
,向其中添加一个值将无法实现我想要的效果
那么有人知道从int.MinValue
到int.MaxValue
获取随机数的好方法吗
更新:
请注意,较低的范围可以是
int.MinValue
,但也可以是其他范围。如果我知道它总是int.MinValue
,那么问题就简单多了。这个方法可以给你一个任意整数范围内的随机整数。如果最大限制小于int.MaxValue,则它使用普通的Random.Next(Int32,Int32),但在上限上加1以包含其值。如果不是,但下限值大于int.MinValue,则会将下限值降低1,以将范围1移动到结果中加1的范围以下。最后,如果两个限值都是int.MinValue和int.MaxValue,它会生成一个随机整数“a”,该整数为0或1,概率各为50%,然后它会生成另外两个整数,第一个介于int.MinValue和-1之间,包含2147483648个值,第二个介于0和int.MaxValue之间,也包含2147483648个值,将它们与“a”的值一起使用,选择一个概率完全相等的整数
private int RandomInclusive(int min, int max)
{
if (max < int.MaxValue)
return Random.Next(min, max + 1);
if (min > int.MinValue)
return Random.Next(min - 1, max) + 1;
int a = Random.Next(2);
return Random.Next(int.MinValue, 0) * a + (Random.Next(-1, int.MaxValue) + 1) * (1 - a);
}
private int random inclusive(最小整数,最大整数)
{
如果(最大值<整数最大值)
返回Random.Next(最小值、最大值+1);
如果(最小值>整数最小值)
返回Random.Next(min-1,max)+1;
int a=随机。下一个(2);
返回Random.Next(int.MinValue,0)*a+(Random.Next(-1,int.MaxValue)+1)*(1-a);
}
这个怎么样
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();
}
}
}
使用系统;
公开课范例
{
公共静态void Main()
{
随机rnd=新随机();
int最小值=最大值;
int最大值=最小值;
Console.WriteLine(“\n20个从10到20的随机整数:”);
对于(int-ctr=1;ctr嗯,我有一个技巧。我不确定我会把它描述为一个“好技巧”,但我觉得它可能会奏效
公共静态类扩展
{
公共静态int NextInclusive(此随机rng、int minValue、int maxValue)
{
if(maxValue==int.maxValue)
{
var字节=新字节[4];
下个字节(字节);
返回BitConverter.ToInt32(字节,0);
}
返回rng.Next(最小值,最大值+1);
}
}
因此,基本上是一种扩展方法,如果上界为int.MaxValue
,则只需生成四个字节,然后转换为int
,否则只需使用标准的Next(int,int)
重载即可
请注意,如果maxValue
是int.maxValue
,它将忽略minValue
。我想我没有解释这一点…将范围一分为二,并补偿maxValue
:
r.Next(2) == 0 ? r.Next(int.MinValue, 0) : (1 + r.Next(-1, int.MaxValue))
r.Next(int.MinValue, 0) - (r.Next(2) == 0 ? 0 : int.MinValue)
如果我们使范围大小相等,我们可以用不同的数学得到相同的结果。这里我们依赖于以下事实:int.MinValue=-1-int.MaxValue
:
r.Next(2) == 0 ? r.Next(int.MinValue, 0) : (1 + r.Next(-1, int.MaxValue))
r.Next(int.MinValue, 0) - (r.Next(2) == 0 ? 0 : int.MinValue)
你可以试试这个。有点粗糙,但可以得到最小值和最大值
static void Main(string[] args)
{
int x = 0;
var r = new Random();
for (var i = 0; i < 32; i++)
x = x | (r.Next(0, 2) << i);
Console.WriteLine(x);
Console.ReadKey();
}
static void Main(字符串[]args)
{
int x=0;
var r=新的随机变量();
对于(变量i=0;i<32;i++)
x=x |(r.Next(0,2)据我所知,您希望随机输出一个介于-2.147.483.648和+2.147.483.647之间的值。但问题是,随机给定这些值只会给出-2.147.483.648到+2.147.483.64之间的值,因为最大值是互斥的
选项0:把东西拿走,学会不用它
道格拉斯·亚当斯(Douglas Adams)不是一名程序员,但他给了我们一些很好的建议:“使任何东西看不见所涉及的技术是如此的复杂,以致于九千九百九十九亿、九亿九千九百万、九百九十九万九千九百九十九倍于一万亿次。只要把东西拿走,不用它,就更简单、更有效了。”
这种情况可能就是这样
选项1:我们需要更大的随机数!
Random.Next()使用Int32作为参数。我可以考虑的一个选项是使用另一个随机函数,该函数可以将下一个更高级别的整数(Int64)作为输入。Int32隐式转换为Int64。Int64 Number=Int64(Int32.MaxValue)+1;
但顺便说一句,要做到这一点,您必须跳出.NET库。在这一点上,您最好查找包含Max的随机变量
但我认为它必须排除一个值是有数学原因的
选项2:滚动更多
另一种方法是使用两次随机调用——每次调用范围的一半——然后将它们相加
Number1 = rng.Next(-2.147.483.648, 0);
Number2 = rng.Next(0, 2.147.483.647);
resut = Number1 + Number2;
然而,我90%肯定这会破坏随机分布。我的p&p RPG经验给了我一些骰子机会方面的经验,我知道一个事实是掷2个骰子(或相同的2次)将得到与一个特定模具非常不同的结果分布。如果您不需要此随机分布,这是一个选项。但如果您不太关心分布,则值得检查
选项3:您需要全量程吗?还是只需要最小值和最大值就可以了?
我假设您正在进行某种形式的测试,并且需要Int.MaxValue和Int.MinValue都在范围内。但是您是否也需要介于两者之间的所有值,或者您可以不使用其中一个值?
如果你
int random(Random rnd, int min, int max)
{
return Convert.ToInt32(rnd.NextDouble() * (max - min) + min);
}
public static class RandomExtensions
{
private const long IntegerRange = (long)int.MaxValue - int.MinValue;
public static int NextInclusive(this Random random, int minValue, int maxValue)
{
if (minValue > maxValue)
{
throw new ArgumentOutOfRangeException(nameof(minValue));
}
var buffer = new byte[4];
random.NextBytes(buffer);
var a = BitConverter.ToInt32(buffer, 0);
var b = a - (long)int.MinValue;
var c = b * (1.0 / IntegerRange);
var d = c * ((long)maxValue - minValue + 1);
var e = (long)d + minValue;
return (int)e;
}
}
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(-451732719).NextInclusive(int.MinValue, int.MaxValue); // returns int.MinValue
new Random(-394328071).NextInclusive(int.MinValue, int.MaxValue); // returns int.MaxValue
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);
}
}
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
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);
}
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
class InclusiveRandom
{
private readonly Random rnd = new Random();
public byte Next(byte min, byte max) => (byte)NextHelper(min, max);
public sbyte Next(sbyte min, sbyte max) => (sbyte)NextHelper(min, max);
public short Next(short min, short max) => (short)NextHelper(min, max);
public ushort Next(ushort min, ushort max) => (ushort)NextHelper(min, max);
public int Next(int min, int max) => (int)NextHelper(min, max);
public uint Next(uint min, uint max) => (uint)NextHelper(min, max);
public long Next(long min, long max) => (long)NextHelper(min, max);
public ulong Next(ulong min, ulong max) => (ulong)NextHelper(min, max);
private BigInteger NextHelper(BigInteger min, BigInteger max)
{
if (max <= min)
throw new ArgumentException($"max {max} should be greater than min {min}");
return min + RandomHelper(max - min);
}
private BigInteger RandomHelper(BigInteger bigInteger)
{
byte[] bytes = bigInteger.ToByteArray();
BigInteger random;
do
{
rnd.NextBytes(bytes);
bytes[bytes.Length - 1] &= 0x7F;
random = new BigInteger(bytes);
} while (random > bigInteger);
return random;
}
}
var rnd = new InclusiveRandom();
var frequency = Enumerable.Range(sbyte.MinValue, sbyte.MaxValue - sbyte.MinValue + 1).ToDictionary(i => (sbyte)i, i => 0ul);
var count = 100000000;
for (var i = 0; i < count; i++)
frequency[rnd.Next(sbyte.MinValue, sbyte.MaxValue)]++;
foreach (var i in frequency)
chart1.Series[0].Points.AddXY(i.Key, (double)i.Value / count);
chart1.ChartAreas[0].AxisY.StripLines
.Add(new StripLine { Interval = 0, IntervalOffset = 1d / 256, StripWidth = 0.0003, BackColor = Color.Red });
class Program
{
private static Int64 _segmentsQty;
private static double _step;
private static Random _random = new Random();
static void Main()
{
InclusiveRandomPrep();
for (int i = 1; i < 20; i++)
{
Console.WriteLine(InclusiveRandom());
}
Console.ReadLine();
}
public static void InclusiveRandomPrep()
{
_segmentsQty = (Int64)int.MaxValue - int.MinValue;
_step = 1.0 / _segmentsQty;
}
public static int InclusiveRandom()
{
var randomDouble = _random.NextDouble();
var times = randomDouble / _step;
var result = (Int64)Math.Floor(times);
return (int)result + int.MinValue;
}
}
public static int NextIntegerInclusive(this Random r, int min_value, int max_value)
{
if (max_value < min_value)
{
throw new InvalidOperationException("max_value must be greater than min_value.");
}
long offsetFromZero =(long)min_value; // e.g. -2,147,483,648
long bound = (long)max_value; // e.g. 2,147,483,647
bound -= offsetFromZero; // e.g. 4,294,967,295 (uint.MaxValue)
bound += Math.Sign(bound); // e.g. 4,294,967,296 (uint.MaxValue + 1)
return (int) (Math.Round(r.NextDouble() * bound) + offsetFromZero); // e.g. -2,147,483,648 => 2,147,483,647
}
static class RandomExtension
{
private static readonly byte[] bytes = new byte[sizeof(int)];
public static int InclusiveNext(this Random random, int min, int max)
{
if (max < int.MaxValue)
// can safely increase 'max'
return random.Next(min, max + 1);
// now 'max' is definitely 'int.MaxValue'
if (min > int.MinValue)
// can safely decrease 'min'
// so get ['min' - 1, 'max' - 1]
// and move it to ['min', 'max']
return random.Next(min - 1, max) + 1;
// now 'max' is definitely 'int.MaxValue'
// and 'min' is definitely 'int.MinValue'
// so the only option is
random.NextBytes(bytes);
return BitConverter.ToInt32(bytes, 0);
}
}
public static class RandomExtension
{
public static int NextInclusive(this Random random, int minValue, int maxValue)
{
var randInt = random.Next(minValue, maxValue);
var plus = random.Next(0, 2);
return randInt + plus;
}
}