我需要一个方法,它从min到max返回随机数,两个数字都包含在内。我在Stephen Toub和Shawn Farkas的文章.NET Matters: Tales from the CryptoRandom中找到了一些代码,其中的方法看起来像这样:
// Note - maxValue is excluded!
public static int GetRandomIntBetween(int minValue, int maxValue)
{
if (minValue > maxValue) throw new ArgumentOutOfRangeException("minValue");
if (minValue == maxValue) return minValue;
var rng = new RNGCryptoServiceProvider();
var uint32Buffer = new byte[4];
long diff = maxValue - minValue;
while (true)
{
rng.GetBytes(uint32Buffer);
uint rand = BitConverter.ToUInt32(uint32Buffer, 0);
const long max = (1 + (long)int.MaxValue);
long remainder = max % diff;
if (rand < max - remainder)
{
return (int)(minValue + (rand % diff));
}
}
}
我尝试将maxValue包含在内:
public static int GetRandomIntBetween(int minValue, int maxValue)
{
if (minValue > maxValue) throw new ArgumentOutOfRangeException("minValue");
if (minValue == maxValue) return minValue;
// Make maxValue inclusive.
maxValue++;
var rng = new RNGCryptoServiceProvider();
var uint32Buffer = new byte[4];
long diff = maxValue - minValue;
while (true)
{
rng.GetBytes(uint32Buffer);
uint rand = BitConverter.ToUInt32(uint32Buffer, 0);
const long max = (1 + (long)int.MaxValue);
long remainder = max % diff;
if (rand < max - remainder)
{
return (int)(minValue + (rand % diff));
}
}
}
看起来很奇怪,但似乎我可以按原样保留前两个检查,即使语义略有不同,它仍然有效。结果数据看起来也不错。我错过了什么或者我的改变好吗?
PS - 我问这个是因为生成随机数显然是一个非常棘手的问题,并且希望确保我的方法是正确的。答案 0 :(得分:1)
您的更改是正确的,[a,b]
之间的随机整数是[a,b+1[
之间的随机整数。
只要maxValue不是int.MaxValue,那么++就会溢出,所以不更改maxValue并将更改移动到diff的计算会更安全:
long diff = (long)maxValue - minValue + 1;
但是,原始函数中的第二次检查显然是错误的,如果minValue == maxValue
,则返回minValue不是minValue和maxValue之间的值。
答案 1 :(得分:0)
Look at my solution (click there)
您可以在课程中添加其他方法:
public int NextInclusive(int minValue, int maxValue) {
return Next(minValue, maxValue + 1);
}