【发布时间】:2014-01-19 16:03:45
【问题描述】:
有谁知道为什么 RNGCryptoServiceProvider 在尝试获得大于 300,000,000 的数字时会失败卡方检验。
我尝试获取 0-1,000,000,000 范围内的随机数,结果卡方检验失败,0-300,000,000 范围内的数字出现的次数多于其他数字。
最终我将大数形式组合成小数 (0-99 *100M + 0-99,999,999) 并通过卡方检验。
谁能解释这个异常现象?
我使用以下代码获取数字
[Timeout(TestTimeout.Infinite), TestMethod]
public void TestMethodStatistic()
{
Dictionary<long, long> appearances = new Dictionary<long, long>();
UInt64 tenBillion = 10000000000;
for (UInt64 i = 0; i < 10000000; i++)
{
UInt64 random = GetSIngleRandomNumberInternal() % tenBillion;
UInt64 bucket = random /10000000;
if (!appearances.ContainsKey(Convert.ToInt64(bucket)))
{
appearances.Add(Convert.ToInt64(bucket), 0);
}
appearances[Convert.ToInt64(bucket)]++;
}
string results = "\nBucket Id\tcount\n";
foreach (var appearance in appearances)
{
results += appearance.Key+"\t"+ appearance.Value +"\n";
}
File.AppendAllText(@"C:\Result.txt",results);
}
private RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider();
private UInt64 GetSIngleRandomNumberInternal()
{
byte[] randomNumBytes = new byte[sizeof(UInt64)];
rngCsp.GetBytes(randomNumBytes);
return BitConverter.ToUInt64(randomNumBytes, 0);
}
获取 Result.txt 文件并将内容复制到 Excel。 使它成为一个表并添加 2 列 1 是值为 100000 的预期结果,第二个是卡方检验,值为 "=CHISQ.TEST([count],[[expected ]])"
当卡方检验的值小于 0.1 时,我们就有问题了。
【问题讨论】:
-
请出示您的测试代码。
-
请将完整代码编辑到您的问题中 - 不要使用 cmets,也不要只包含一个方法。
-
您认为框架代码有问题。您的测试代码很可能是错误的。错误几乎总是你的错误,而不是框架。
-
但它没有通过卡方检验,这意味着它不够随机......
-
一个问题是你在使用余数技术时引入了偏差。有关说明,请参阅 ericlippert.com/2013/12/16/…。