2009-12-02 3 views
0

Я знаю, что этот вопрос задавался снова и снова. Мне нужны случайные числа между 0-9. Я использую следующий код:Создание случайных чисел в C

srand(time()); 
int r; 
for (;;) 
{ 
    while(condition) 
    { 
     r = rand()%10; 
     // ... 
     // ... 
    } 
} 

Теперь я получаю одинаковую последовательность чисел для каждой итерации цикла for. Может ли кто-нибудь предоставить мне правильный код?

PS - Мой компилятор не распознает arcrandom().

+10

Можете ли вы разместить свой полный код? В этом коде есть много ошибок, и вы, очевидно, пропустили некоторые «несущественные» части, которые могут быть причиной этой проблемы. Если ваш код слишком длинный для публикации, попробуйте уменьшить его до простейшего примера, который воспроизводит ошибку. –

+2

Если вы «знаете, что этот вопрос задавали снова и снова», почему вы спрашиваете его еще раз, вместо того, чтобы искать один из более ранних ответов? –

+0

Я искал все решения, но не смог найти убедительного ответа. Почему все так эмоциональны в этом вопросе. У меня никогда не было так много просмотров так быстро! – Bruce

ответ

13

Эта проблема проистекает из того факта, что на некоторых реализациях младшие разряды rand() не очень случайны. Цитируя man page:

«Если вы хотите, чтобы сгенерировать случайное число от 1 до 10, вы всегда должны делать это с помощью битов высокого порядка, как и в

j = 1 + (int) (10.0 * (rand()/(RAND_MAX + 1.0))); 

и никогда ничем напоминает

j = 1 + (rand() % 10); 

(который использует младшие разряды). "

+0

Я пробовал это раньше .. Это не работает – Bruce

+2

@Peter: Ну, я не могу помочь вам тогда ... Вы, вероятно, делаете что-то еще неправильно что вы не заметили и не скопировали код примера, который вы опубликовали. Кажется, в этом нет ничего плохого. –

+0

Ты, наверное, прав Мартиньо. Я снова посмотрю на свой код. Спасибо за ответ – Bruce

7

Вероятно, вы вызываете эту функцию во втором, и srand будет посеян с той же секунды. Вы должны только позвонить srand один раз в начале основного.

+1

Решением может быть использование другого источника семян, такого как таймер с более высоким разрешением. –

+0

В коде 'srand' вызывается только один раз, а не внутри цикла. Это не делает последовательность повторять каждую итерацию –

+2

Martinho, вы знаете это как? Он вызывается один раз * внутри функции, в которой он находится *, что может быть или не быть 'main()'. – GManNickG

0
srand(time(0)); 

r = rand() % (max+1); 

//r will be a random number between 0 and max. 

Я могу только думать, что вы не инициализировали правильно, или ваш отредактированный код был неправильно отредактирован.

+2

К сожалению! 'rand()% max + 1' отличается от' rand()% (max + 1) '. – pmg

+0

Durrr! Это то, что происходит от быстрой печати. –

+1

Ирония - это «или ваш отредактированный код неправильно исправлен». –

0

Ваш код не компилируется - for() не действует C.

Вы уверены, что вы звоните srand только один раз, в начале программы и перед любыми rand звонков? Вызов srand в цикле объяснил бы это поведение.

+0

В цикле for есть условие внутри него. Это не относится к моему вопросу ... Да, я вызываю srand() только один раз, до того, как любой rand вызывает – Bruce

+0

@Peter: если это не имеет значения, вы можете записать его как ' for (;;) ', который действителен и никого не расстроит. –

+1

Мой плохой. Я не хотел расстраивать вас – Bruce

0

У вас есть случайный()?

random() man page

Я сделал простую программу:

int i; 
for(i=0;i<40;i++) 
printf("%d",rand()%10); 

И адресности 7938024839052273790239970398657627039991 - не повторять здесь. Как долго вы можете продолжить карьеру?

1

Удалить все srand() calls from your code.

Добавить один, уникальный звонок перед первым утверждением в main().

int main(void) { 
    int foo = 42; 
    int bar = baz(42); 

    srand(time(0)); 
    /* rest of your program */ 
    return 0; 
} 
2

Многие pseudorandom generators имеют наблюдаемый период.
Если вам нужен длительный период, используйте алгоритм от Knuth 2. Он имеет период около 2^55 и прост в реализации.
RANARRAY

+0

Биты младшего разряда rand() имеют короткий период. Но ОП говорит, что работа вокруг этого не решает проблему ... –

0

Единственный возможный способ, которым Вы могли бы получать точную же последовательность чисел, если есть вызов srand() где-то в коде, который вы не показали нам. Это может быть глубоко внутри вызова функции где-то.

Способ исправить это будет, чтобы найти дополнительный звонок srand и удалите его. Однако этот быстрый хак может вам начать:

static int seed = time(); 
int r; 
for (;;) 
{ 
    srand(seed++); 
    while(condition) 
    { 
     r = rand()%10; 
     // ... 
     // ... 
    } 
} 
0

В зависимости от ваших требований к статистической случайности вы могли бы найти лучше угробить псевдо генератор случайных чисел и попробовать внешний источник.

random.org и randomnumbers.info (среди прочего) предоставят действительно случайные числа для загрузки, которые libcurl должен обрабатывать для вас.

Смежные вопросы