Random 我如何解释Diehard的结果以获得更大的正义

Random 我如何解释Diehard的结果以获得更大的正义,random,Random,这是一个关于SO问题的问题;我不认为它属于meta,尽管它的定义是sp,但如果有人认为它应该用于数学、交叉验证等,请让我知道 背景: @ForceBru询问如何使用rand()生成64位随机数@nwellnhof提供了一个被接受的答案,基本上是取5个随机数中的低15位(因为MAXRAND显然在至少一些编译器上只能保证为15位),然后将它们粘在一起,然后删除前11位(15*5-64=11)@NikBougalis评论说,虽然这似乎合理,但它不会通过许多随机变量的统计测试@Foon(我)要求提供一份

这是一个关于SO问题的问题;我不认为它属于meta,尽管它的定义是sp,但如果有人认为它应该用于数学、交叉验证等,请让我知道

背景: @ForceBru询问如何使用rand()生成64位随机数@nwellnhof提供了一个被接受的答案,基本上是取5个随机数中的低15位(因为MAXRAND显然在至少一些编译器上只能保证为15位),然后将它们粘在一起,然后删除前11位(15*5-64=11)@NikBougalis评论说,虽然这似乎合理,但它不会通过许多随机变量的统计测试@Foon(我)要求提供一份它将失败的测试的引用或示例@尼卡里斯的回答并没有阐明我的意思@戴维斯沃茨建议与迪哈德比赛

所以,我跑得更努力了。我用这个算法进行了测试

unsigned long long llrand() {
    unsigned long long r = 0;

    for (int i = 0; i < 5; ++i) {
        r = (r << 15) | (rand() & 0x7FFF);
    }

    return r & 0xFFFFFFFFFFFFFFFFULL;
}
有问题的算法通过两个测试返回,分别显示ntuple=28的rgb_滞后_和的弱点,以及ntuple=8的一个sts_序列

仅仅使用rand()在很多测试中都失败了,大概是因为我取了一个具有15位随机性的数字,并将其作为32位随机性进行传递

一次使用rand()的低8位,对于N元组为2的rgb_滞后_和,(编辑)失败的dab_单位,元组为12

我的问题是:

  • 我是否正确解释了8位随机测试的结果,即假设其中一项测试(标记为“良好”;记录在案,对于标记为“可疑”的迪哈德测试之一,它也返回为弱测试),结果为弱测试,一项为失败测试,则应怀疑rand()的随机性
  • 我是否正确地解释了被测算法的结果(也就是说,这也应该被怀疑)
  • 给出了测试结果为弱的描述(例如,对于sts_序列,检查特定大小的位模式分布是否有效),我是否能够确定可能的偏差
  • 如果3,既然我不是,有人能指出我应该看到什么吗
    编辑:理解rand()并不一定是伟大的。此外,我试图思考哪些值不太可能,并推测零、最大值或重复的数字可能是。。。但是做一个100000000次的测试,这个比率非常接近每2^15次中有1次的预期值(例如,在100000000次运行中,我们看到30512个零、30444个最大值和30301个重复,bc说30512*2^15是999817216;其他运行具有类似的比率,包括最大值和/或重复值大于零的情况。

    当您运行时,您真正需要关注的列是p值列

    p值列本质上说:“这是真实随机数产生此结果的概率。”您希望它在0和1之间均匀分布

    您还需要对可疑案例多次运行它。例如,如果您有一个p值为(例如).03的列,那么如果您重新运行它,您仍然有.03(而不是更高的值)然后你可以很有信心你的随机数生成器在测试中表现很差,这不仅仅是3%的侥幸。然而,如果你得到一个很高的值,那么你可能看到的是统计上的侥幸。但这是双向的


    最终,了解随机或伪随机过程的事实是很困难的。但是使用Diehard,您可以大致了解许多事情。

    只调用
    rand()
    的问题是,即使
    rand\u MAX==INT\u MAX
    ,它也会返回一个非负符号INT,因此MSB始终为零(通常为31个随机位)。还要注意,
    rand()
    返回的数字的质量仅仅取决于各自C库中的实现。在质量、速度和内存使用之间总是要进行权衡。据说Microsoft的CRT实现特别差。如果您需要高质量的随机数,请不要依赖
    rand()
    void rand_test()
    {
    int x;
    srand(1);
      while(1)
        {
          x = rand();
          fwrite(&x,sizeof(x),1,stdout);
        }
    
    void rand_byte_test()
    {
      srand(1);
      while(1)
        {
          x = rand();
          c = x % 256;
          fwrite(&c,sizeof(c),1,stdout);
        }
    }