.NET中Random类实现的质量如何?

hou*_*uen 32 .net c# random

关于Random.NET Framework 4.6中的类的实现,我有两个问题(此处提供的代码):

  1. 在构造函数的末尾设置Seed参数的基本原理是什么1?它似乎是从C(第二版)中的Numerical Recipes复制粘贴的,它有一定意义,但它在C#中没有.

  2. 在书中(Numerical Recipes in C(2nd Ed.))中直接说明该inextp字段被设置为值,31因为:

常数31是特殊的; 见Knuth.

但是,在.NET实现中,此字段设置为value 21.为什么?代码的其余部分似乎严格遵循书中的代码,除了这个细节.

DGi*_*bbs 24

关于这个intexp问题,这是一个错误,微软承认并且由于向后兼容性问题而拒绝修复.

实际上,您已经发现了Random实现的真正问题.我们已经在团队内部和我们的一些合作伙伴讨论过这个问题,并得出结论,我们现在无法解决问题.原因是一些应用程序依赖于以下事实:当使用相同种子初始化时,生成器产生相同的伪随机序列.即使变化更好,但一旦迁移到"固定"版本,它将破坏做出此假设的应用程序.

  • 该算法保持56个随机整数的缓冲区,这些整数基于种子值进行初始化.缓冲区中的两个索引应保持相隔31个位置(在这种情况下为21),伪随机数计算为这些索引处的值的差值.您无法在不更改输出的情况下更改索引的位置,因为它们会引用不同的值. (5认同)

Kev*_*art 7

对于更多背景:

前段时间我完全分析了这个实现.我发现了一些差异.

第一个(完全没问题)是一个不同的大值(MBIG).Numerical Recipies声称Knuth明确表示任何大值都应该有效,因此这不是问题,而且Microsoft合理地选择使用32位整数的最大值.

你提到的第二个是那个常数.那是一个大问题.在最低限度,它将大大减少期限.据报道,效果实际上比这更糟糕.

但接下来是另一个特别令人讨厌的差异.它实际上是保证偏置输出(因为它直接这样做),并且也可能影响RNG的周期.

那第二个问题又是什么呢?当.NET第一次出现时,微软没有意识到他们编码的RNG在两端都是包容性的,并且他们在最大程度上将其记录为独占.为了解决这个问题,安全团队添加了一条相当邪恶的代码:if (retVal == MBIG) retVal--;.这是非常不幸的,因为正确的解决方案实际上只有4个添加的字符(加上空格).

正确的修改会一直改变MBIGint.MaxValue-1,但开关Sample()使用MBIG+1(即使用保持int.MaxValue).这样可以保证样品的范围[ MBIG0.0,1.0 ]不会引入任何偏差,只会改变Knuth所说的数值接收的值非常好.