Rand()% 14 генерирует только значения 6 или 13

Всякий раз, когда я запускаю следующую программу, возвращаемые значения всегда равны 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;
}

Я запустил программу почти сто раз в течение сегодняшнего дня и вчера.

Может ли кто-нибудь сказать мне, что я делаю неправильно?

Спасибо.

EDIT: Кстати, если я изменяю диапазон rand(), чтобы сказать 13 или 15, он работает нормально.

Ответы

Ответ 1

Я могу воспроизвести проблему в Mac OS X 10.9 с Xcode 5 - похоже, что это может быть ошибка или, по крайней мере, ограничение с rand()/srand() на OS X 10.9.

Я рекомендую вместо этого использовать arc4random(), который работает намного лучше, чем rand(), и который не требует, чтобы вы рандомизировали семя:

#include <iostream>
#include <cstdlib>

using namespace std;

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

Тест:

$ 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
$

Ответ 2

Per wikipedia множитель, используемый в генераторе случайных чисел Apple MCG, равен 16807. Это делится на 7, поэтому первое случайное число, созданное после srand() будет иметь только один бит энтропии mod 14 (т.е. он может принимать только два значения).

Это дерьмовый RNG, который у них есть. Однако простое решение состоит в том, чтобы просто вызвать rand() несколько раз сразу после srand и отбросить результаты.

Ответ 3

rand() % 14 часто является слабым генератором случайных чисел. Вероятно, вы получите лучшие результаты с этим

(int)(14*(rand()/(RAND_MAX + 1.0)))