srand(time(null));
printf("%d", rand());
Дает большое случайное число (0-32000ish), но мне нужно только около 0-63 или 0-127, хотя я не уверен, как это сделать. Любая помощь?
srand(time(null));
printf("%d", rand());
Дает большое случайное число (0-32000ish), но мне нужно только около 0-63 или 0-127, хотя я не уверен, как это сделать. Любая помощь?
rand() % (max_number + 1 - minimum_number) + minimum_number
Итак, для 0-65:
rand() % (65 + 1 - 0) + 0
(очевидно, вы можете оставить 0, но он там для полноты).
Обратите внимание, что это слегка смещает случайность, но, вероятно, нечего беспокоиться о том, что вы не делаете что-то особенно чувствительное.
проверьте здесь
http://c-faq.com/lib/randrange.html
Для любого из этих методов, при необходимости, можно смещать диапазон; числа в диапазоне [M, N] могут быть сгенерированы с чем-то вроде
M + rand() / (RAND_MAX / (N - M + 1) + 1)
Вы можете использовать это:
int random(int min, int max){
return min + rand() / (RAND_MAX / (max - min + 1) + 1);
}
От:
comp.lang.c Список часто задаваемых вопросов · Вопрос 13.16
В: Как я могу получить случайные целые числа в определенном диапазоне?
A: Очевидный путь,
rand() % N /* POOR */
(который пытается вернуть числа от 0 до N-1) плохой, потому что младшие биты многих генераторов случайных чисел являются удручающе неслучайными. (См. Вопрос 13.18.) Лучший метод - это что-то вроде
(int)((double)rand() / ((double)RAND_MAX + 1) * N)
Если вы не хотите использовать с плавающей запятой, другой метод
rand() / (RAND_MAX / N + 1)
Если вам просто нужно сделать что-то с вероятностью 1/N, вы можете использовать
if(rand() < (RAND_MAX+1u) / N)
Все эти методы, очевидно, требуют знания RAND_MAX (который ANSI #defines в <stdlib.h>) и предполагают, что N намного меньше, чем RAND_MAX. Когда N близко к RAND_MAX и если диапазон генератора случайных чисел не кратен N (т.е. Если (RAND_MAX + 1)% N! = 0), все эти методы выходят из строя: некоторые выходы происходят чаще, чем другие. (Использование плавающей запятой не помогает; проблема в том, что rand возвращает RAND_MAX + 1 отличное значение, которое не всегда может быть равномерно разделено на N сегментов.) Если это проблема, единственное, что вы можете сделать, это вызвать rand несколько раз, отбрасывая определенные значения:
unsigned int x = (RAND_MAX + 1u) / N; unsigned int y = x * N; unsigned int r; do { r = rand(); } while(r >= y); return r / x;
Для любого из этих методов просто сместить диапазон, если это необходимо; числа в диапазоне [M, N] могут быть сгенерированы с чем-то вроде
M + rand() / (RAND_MAX / (N - M + 1) + 1)
(Между прочим, обратите внимание, что RAND_MAX является константой, сообщающей вам, что является фиксированным диапазоном функции rand библиотеки C. Вы не можете установить RAND_MAX на какое-то другое значение, и нет способа запросить возвращаемые числа rand в другом диапазоне.)
Если вы начинаете с генератора случайных чисел, который возвращает значения с плавающей запятой от 0 до 1 (например, последняя версия PMrand, на которую ссылается вопрос 13.15, или drand48 в вопросе 13.21), все, что вам нужно сделать, чтобы получить целые числа из От 0 до N-1 - умножьте выход этого генератора на N:
(int)(drand48() * N)
Ссылки: K & R2 Sec. 7.8.7 с. 168
PCS Sec. 11 стр. 172
Взяв по модулю результат, как утверждают другие авторы, вы получите нечто почти случайное, но не совсем так.
Рассмотрим этот крайний пример. Предположим, вы хотите смоделировать бросок монеты, возвращая либо 0, либо 1. Вы можете сделать это:
isHeads = ( rand() % 2 ) == 1;
Выглядит достаточно безобидно, верно? Предположим, что RAND_MAX только 3. Это намного выше, конечно, но дело здесь в том, что существует смещение, когда вы используете модуль, который не делит RAND_MAX равномерно. Если вам нужны высококачественные случайные числа, у вас возникнут проблемы.
Рассмотрим мой пример. Возможные результаты:
rand() freq. rand() % 2
0 1/3 0
1 1/3 1
2 1/3 0
Следовательно, "хвосты" будут встречаться в два раза чаще, чем "головы"!
Мистер Этвуд обсуждает этот вопрос в этой статье об ужасах кодирования
Как отмечали другие, просто использование модуля будет искажать вероятности для отдельных чисел, так что предпочтительны меньшие числа.
Очень острое и хорошее решение этой проблемы используется в Java java.util.Random
class:
public int nextInt(int n) {
if (n <= 0)
throw new IllegalArgumentException("n must be positive");
if ((n & -n) == n) // i.e., n is a power of 2
return (int)((n * (long)next(31)) >> 31);
int bits, val;
do {
bits = next(31);
val = bits % n;
} while (bits - val + (n-1) < 0);
return val;
}
Мне потребовалось некоторое время, чтобы понять, почему это работает, и я оставляю это как упражнение для читателя, но это довольно сжатое решение, которое обеспечит равные вероятности чисел.
Важной частью этого фрагмента кода является условие цикла while
, которое отклоняет числа, которые попадают в диапазон чисел, что в противном случае приведет к неравномерному распределению.
double scale = 1.0 / ((double) RAND_MAX + 1.0);
int min, max;
...
rval = (int)(rand() * scale * (max - min + 1) + min);
Если вы не слишком заботитесь о "случайности" младших бит, просто rand()% HI_VAL.
также:
(double)rand() / (double)RAND_MAX; // lazy way to get [0.0, 1.0)
Наивный способ сделать это:
int myRand = rand() % 66; // for 0-65
Вероятно, это будет очень незначительное неравномерное распределение (в зависимости от вашего максимального значения), но оно довольно близко.
Чтобы объяснить, почему это не совсем однородно, рассмотрите этот очень упрощенный пример:
Предположим, что RAND_MAX равен 4, и вам нужно число от 0 до 2. Возможные значения, которые вы можете получить, показаны в этой таблице:
rand() | rand() % 3
---------+------------
0 | 0
1 | 1
2 | 2
3 | 0
Увидеть проблему? Если ваше максимальное значение не является четным делителем RAND_MAX, вы, скорее всего, будете выбирать небольшие значения. Однако, поскольку RAND_MAX обычно 32767, смещение, вероятно, будет достаточно маленьким, чтобы избежать неприятностей для большинства целей.
Существуют различные способы обойти эту проблему; см. здесь для объяснения того, как обрабатывает Java Random
.
Обновлено, чтобы не использовать #define
double RAND(double min, double max)
{
return (double)rand()/(double)RAND_MAX * (max - min) + min;
}
rand() вернет числа от 0 до RAND_MAX, что составляет не менее 32767.
Если вы хотите получить число в пределах диапазона, вы можете просто использовать modulo.
int value = rand() % 66; // 0-65
Для большей точности ознакомьтесь с этой статьей. В нем обсуждается, почему modulo не обязательно хорош (плохие дистрибутивы, особенно на высоком конце), и предоставляет различные варианты.
Этот ответ фокусируется не на случайности, а на арифметическом порядке. Чтобы получить число в диапазоне, обычно мы можем сделать это так:
// the range is between [aMin, aMax]
double f = (double)rand() / RAND_MAX;
double result = aMin + f * (aMax - aMin);
Однако существует вероятность переполнения (aMax - aMin). Например, aMax = 1, aMin = -DBL_MAX. Более безопасный способ - написать так:
// the range is between [aMin, aMax]
double f = (double)rand() / RAND_MAX;
double result = aMin - f * aMin + f * aMax;
Исходя из этой концепции, что-то подобное может вызвать проблемы.
rand() % (max_number + 1 - minimum_number) + minimum_number
// 1. max_number + 1 might overflow
// 2. max_number + 1 - min_number might overflow
Я думаю, что следующее полу справа. Прошло некоторое время с тех пор, как я коснулся C. Идея состоит в том, чтобы использовать деление, поскольку модуль не всегда дает случайные результаты. Я добавил 1 в RAND_MAX, так как есть много возможных значений, исходящих из rand, включая 0. И поскольку диапазон также равен 0 включительно, я добавил там 1. Я думаю, что математика правильно организована, чтобы избежать целых математических задач.
#define MK_DIVISOR(max) ((int)((unsigned int)RAND_MAX+1/(max+1)))
num = rand()/MK_DIVISOR(65);
Если вы заботитесь о качестве ваших случайных чисел, не используйте rand()
используйте другие prng, такие как http://en.wikipedia.org/wiki/Mersenne_twister или один из других высококачественных prng там
тогда просто двигайтесь с модулем.
Просто чтобы добавить некоторые дополнительные детали к существующим ответам.
Операция mod %
всегда будет выполнять полное деление и, следовательно, даст остаток меньше делителя.
х% у = х - (у * этаж ((х/у)))
Пример функции поиска случайного диапазона с комментариями:
uint32_t rand_range(uint32_t n, uint32_t m) {
// size of range, inclusive
const uint32_t length_of_range = m - n + 1;
// add n so that we don't return a number below our range
return (uint32_t)(rand() % length_of_range + n);
}
Еще одно интересное свойство в соответствии с вышеизложенным:
х% у = х, если х <у
const uint32_t value = rand_range(1, RAND_MAX); // results in rand() % RAND_MAX + 1
// TRUE for all x = RAND_MAX, where x is the result of rand()
assert(value == RAND_MAX);
result of rand()
2 cents (ok 4 cents):
n = rand()
x = result
l = limit
n/RAND_MAX = x/l
Refactor:
(l/1)*(n/RAND_MAX) = (x/l)*(l/1)
Gives:
x = l*n/RAND_MAX
int randn(int limit)
{
return limit*rand()/RAND_MAX;
}
int i;
for (i = 0; i < 100; i++) {
printf("%d ", randn(10));
if (!(i % 16)) printf("\n");
}
> test
0
5 1 8 5 4 3 8 8 7 1 8 7 5 3 0 0
3 1 1 9 4 1 0 0 3 5 5 6 6 1 6 4
3 0 6 7 8 5 3 8 7 9 9 5 1 4 2 8
2 7 8 9 9 6 3 2 2 8 0 3 0 6 0 0
9 2 2 5 6 8 7 4 2 7 4 4 9 7 1 5
3 7 6 5 3 1 2 4 8 5 9 7 3 1 6 4
0 6 5
Простое использование rand() даст вам одинаковые случайные числа при многократном запуске программы. т.е. когда вы запускаете вашу программу в первый раз, она выдаст случайное число x, y и z. Если вы запустите программу еще раз, то она выдаст те же числа x, y и z, как я наблюдал.
Решение, которое я нашел, чтобы сохранить его уникальным каждый раз, использует srand()
Вот дополнительный код,
#include<stdlib.h>
#include<time.h>
time_t t;
srand((unsigned) time(&t));
int rand_number = rand() % (65 + 1 - 0) + 0 //i.e Random numbers in range 0-65.
Чтобы установить диапазон вы можете использовать формулу: rand()% (max_number + 1 - минимальный_номер) + минимальный_номер
Надеюсь, поможет!
Вы можете изменить его, добавив% перед функцией rand, чтобы перейти к коду
Например:
rand() % 50
даст вам случайное число в диапазоне от 50. Для вас замените 50 на 63 или 127
Или вы можете использовать это:
rand() / RAND_MAX * 65
Но я не уверен, что это самый случайный или самый быстрый из всех ответов здесь.