rand()有时会连续返回吗?

时间:2014-06-03 09:16:04

标签: c++ c visual-c++ random

我只是好奇,单线程程序可以连续两次调用rand()获得相同的返回值吗?

那么,这个断言会不会发生?

assert(rand() != rand());

4 个答案:

答案 0 :(得分:46)

如果我们能找到一个例子,你问题的答案是"是"。

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char* argv[])
{
  unsigned int i;
  for(i = 0; ; i++) {
    int r = rand();
    if (r == rand()) {
        printf("Oops. rand() = %d; i = %d\n", r, i);
        break;
    }
  }
  return 0;
}

使用Visual Studio 2010在Windows上打印Oops. rand() = 3482; i = 32187

编辑: 使用下面的版本检测2个连续rand()调用返回相同值的所有序列。 C仅指定rand()应返回0到0范围内的&#34;伪随机整数 RAND_MAX&#34;和RAND_MAX应至少为32767。 对PRNG的质量或其实现没有限制,或者其他细节,例如2个连续的rand()调用是否可以返回相同的值。

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char* argv[])
{
  unsigned int i;
  int r1 = rand();
  int r2 = rand();
  for(i = 0; ; i++) {
    if (r1 == r2) {
        printf("Oops. rand() = %d; i = %d\n", r1, i);
    }
    r1 = r2;
    r2 = rand();
  }
  return 0;
}

答案 1 :(得分:30)

我做了我的研究

发现我的编译器(msvc10)的rand实现确实使用了线性同余生成器,就像其他c / c ++编译器一样

线性同余生成器

线性同余生成器使用递归方法。

use the

ptd-&gt; _holdrand(n)永远不会等于ptd-&gt; _holdrand(n + 1),但mod结果将相等。

msvc实施

@nos显示结果

return( ((ptd->_holdrand = ptd->_holdrand * 214013L + 2531011L) >> 16) & 0x7fff );

ptd->_holdrand = 2375716238;
return 3482; (2375716238 >> 16) % 32768
ptd->_holdrand = 228240921;
return 3482; (228240921 >> 16) % 32768

最终答案是rand()将作为我的直觉两次返回相同的值。

答案 2 :(得分:8)

理想的随机rand()函数,如果调用两次,每次都会返回相同的结果,概率为1.0 / RAND_MAX

rand()不是真正的随机数生成器。它是pseudorandom number generator(PRNG),通常为linear congruential类型。

PRNG的内部状态不得在连续呼叫时重复;如果确实如此,rand()会永远陷入同一个数字。对于像middle square method这样设计不佳的算法,可能会发生这种情况。

然而,一些(但不是全部)PRNG实现在其内部状态中具有比在其输出中更多的位。例如,java.util.Random使用48位内部状态,但仅包含其输出中最重要的32位。在这种情况下,(至少在理论上)可以在没有相同内部状态的情况下连续两次获得相同的输出。

答案 3 :(得分:6)

一个好的随机数生成器应该有时连续两次返回相同的值。让我们说它返回正整数0&lt; = r&lt; 2 ^ 31。对于完美的随机数发生器,两个连续数字相同的可能性大约为20亿。 在1000亿次通话中获得两个相同数字的机会大约是10 ^ 15中的一个。