Rand()%14仅生成值6或13

Ken*_*eth 14 c++ random srand

每当我运行以下程序时,返回的值总是6或13.

#include <iostream>
#include <fstream>
#include <ctime>
#include <cstdlib>
using namespace std;

//void randomLegs();
//void randomPush();
//void randomPull();
//void randomMisc();


int main(int argc, const char * argv[])
{
    srand(time(NULL));
    //randomLegs();
    cout << rand() % 14;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在今天和昨天,我已经将程序运行了近百次.

谁能告诉我我做错了什么?

谢谢.

编辑:顺便说一句,如果我将rand()的范围改为13或15,它就可以了.

Sne*_*tel 35

根据维基百科,Apple的MCG随机数生成器中使用的乘数是16807.这可以被7整除,因此后面生成的第一个随机数srand()只有一位熵mod 14(也就是说,它只能取两个值).

他们到达那里是一个糟糕的RNG.但是,一个简单的解决方案就是在之后调用rand()几次srand,并丢弃结果.

  • 顺便说一句,更简单的解决方法是等待大约1800万年,然后再次尝试该程序.此时,`time()`返回的值将足以将"拐角处"的熵推入低位.尝试一下,让我们的后代知道它是如何运作的.:-D (16认同)
  • +1,美丽的解释!我不知道这些东西有多么脆弱.通常我所看到的"你为什么不应该在短距离内模数"的解释只是它在边缘不均匀. (7认同)

Pau*_*l R 8

我可以使用Xcode 5在Mac OS X 10.9上重现这个问题 - 看起来它实际上可能是一个bug,或者至少是OS X 10.9 上的rand()/ 的限制srand().

我建议你使用arc4random(),它比使用更好rand(),并且不需要你随机化种子:

#include <iostream>
#include <cstdlib>

using namespace std;

int main(int argc, const char * argv[])
{
    cout << (arc4random() % 14) << endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

测试:

$ g++ -Wall -O3 srand.cpp && ./a.out
5
$ ./a.out
8
$ ./a.out
0
$ ./a.out
8
$ ./a.out
11
$ ./a.out
8
$ ./a.out
3
$ ./a.out
13
$ ./a.out
9
$
Run Code Online (Sandbox Code Playgroud)

  • 为什么使用另一个库,如果标准库也有其他选择?参见`<random>`,特别是`std :: mt19937`,这是一个已知良好的RNG.它还附带`std :: uniform_int_distribution` (5认同)
  • @PaulR完全正确.另外,更好的解决方案是使用`arc4random_uniform(MAX)`而不是`arc4random()%MAX`. (5认同)
  • 谢谢保罗.这个解决方案很简单,它解决了我的问题. (2认同)
  • @MSalters:`arc4random()`在Mac OS X,iOS和各种BSD平台上非常标准,并且不需要额外的库. (2认同)