1 回答
TA贡献1859条经验 获得超6个赞
这是.Net Random 类的缺陷。
如果您检查源代码,您将在私有方法的实现中看到以下注释GetSampleForLargeRange()
:
// The distribution of double value returned by Sample
// is not distributed well enough for a large range.
// If we use Sample for a range [Int32.MinValue..Int32.MaxValue)
// We will end up getting even numbers only.
这在 Next() 的实现中使用:
public virtual int Next(int minValue, int maxValue) {
if (minValue>maxValue) {
throw new ArgumentOutOfRangeException("minValue",Environment.GetResourceString("Argument_MinMaxValue", "minValue", "maxValue"));
}
Contract.EndContractBlock();
long range = (long)maxValue-minValue;
if( range <= (long)Int32.MaxValue) {
return ((int)(Sample() * range) + minValue);
}
else {
return (int)((long)(GetSampleForLargeRange() * range) + minValue);
}
}
但它不用于从返回的值NextDouble()(它只返回从Sample().
所以答案是NextDouble()分布不均匀。
您可以使用它RNGCryptoServiceProvider
来生成更好的随机数,但创建双精度数有点麻烦。
static void Main()
{
var R = new RNGCryptoServiceProvider();
var bytes = new Byte[8];
for (int i = 0; i < 10_000; i++)
{
R.GetBytes(bytes);
var ul = BitConverter.ToUInt64(bytes, 0) / (1 << 11);
var d = ul / (double)(1UL << 53);
d *= uint.MaxValue;
Console.WriteLine(d);
}
}
- 1 回答
- 0 关注
- 100 浏览
添加回答
举报