我正在开发一个受到严格监管审查的游戏平台。我选择 Math.NET 因为它看起来很合适。不过,我刚刚收到我们审计员发回的评论。
请评论这是否准确以及如何解决?
在RandomSource()中,Next(int, int)定义如下:
public override sealed int Next(int minValue, int maxValue)
{
if (minValue > maxValue)
{
throw new ArgumentException(Resources.ArgumentMinValueGreaterThanMaxValue);
}
if (_threadSafe)
{
lock (_lock)
{
return (int)(DoSample()*(maxValue - minValue)) + minValue;
}
}
return (int)(DoSample()*(maxValue - minValue)) + minValue;
}
这会以与之前相同的方式产生偏差。使用 RNG 中的未缩放值并将其乘以范围,而无需事先消除偏差(除非范围是 2 的幂,否则将存在偏差)。
最佳答案
更新:Math.NET Numerics v3.13 中 Next(minInclusive, maxExclusive)
的实现已更改如下这次讨论。从 v3.13 开始,它不再涉及 float ,而是根据需要使用尽可能多的位对整数进行采样,以支持请求的范围(2 的幂)并拒绝实际范围之外的那些。这样就可以避免在字节采样本身之上添加任何偏差(例如由加密 RNG 提供的)
假设:DoSample()
返回[0,1)
范围内均匀分布的样本( double float )。
将其与范围 R=max-min 相乘将得到范围 [0,R)
内均匀分布的样本。将其转换为整数(本质上是下限)将产生 0,1,2,...,R-1
之一的均匀分布离散样本。我不认为 R 是偶数、奇数或 2 的幂这一事实可能会影响此步骤中的偏差。
计算 100'000'000 个样本的几次运行也没有表明明显的偏差,但这当然不是证据:
var r = new CryptoRandomSource();
long[] h = new long[8];
for (int i = 0; i < 100000000; i++)
{
h[r.Next(2,7)]++;
}
0
0
19996313
20001286
19998092
19998328
20005981
0
0
0
20000288
20002035
20006269
19994927
19996481
0
0
0
19998296
19997777
20001463
20002759
19999705
0
关于c# - Math.NET CryptoRandomSource Next 是有偏差的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39013455/