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 關注
- 123 瀏覽
添加回答
舉報