Подтвердить что ты не робот

Как получить определенный диапазон чисел из rand()?

srand(time(null));

printf("%d", rand());

Дает большое случайное число (0-32000ish), но мне нужно только около 0-63 или 0-127, хотя я не уверен, как это сделать. Любая помощь?

4b9b3361

Ответ 1

rand() % (max_number + 1 - minimum_number) + minimum_number

Итак, для 0-65:

rand() % (65 + 1 - 0) + 0

(очевидно, вы можете оставить 0, но он там для полноты).

Обратите внимание, что это слегка смещает случайность, но, вероятно, нечего беспокоиться о том, что вы не делаете что-то особенно чувствительное.

Ответ 2

проверьте здесь

http://c-faq.com/lib/randrange.html

Для любого из этих методов, при необходимости, можно смещать диапазон; числа в диапазоне [M, N] могут быть сгенерированы с чем-то вроде

M + rand() / (RAND_MAX / (N - M + 1) + 1)

Ответ 3

Вы можете использовать это:

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

Цитата: http://c-faq.com/lib/randrange.html

Ответ 4

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

Рассмотрим этот крайний пример. Предположим, вы хотите смоделировать бросок монеты, возвращая либо 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

Следовательно, "хвосты" будут встречаться в два раза чаще, чем "головы"!

Мистер Этвуд обсуждает этот вопрос в этой статье об ужасах кодирования

Ответ 5

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

Очень острое и хорошее решение этой проблемы используется в 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, которое отклоняет числа, которые попадают в диапазон чисел, что в противном случае приведет к неравномерному распределению.

Ответ 6

double scale = 1.0 / ((double) RAND_MAX + 1.0);
int min, max;
...
rval = (int)(rand() * scale * (max - min + 1) + min);

Ответ 7

Если вы не слишком заботитесь о "случайности" младших бит, просто rand()% HI_VAL.

также:

(double)rand() / (double)RAND_MAX;  // lazy way to get [0.0, 1.0)

Ответ 8

Наивный способ сделать это:

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.

Ответ 9

Обновлено, чтобы не использовать #define

double RAND(double min, double max)
{
    return (double)rand()/(double)RAND_MAX * (max - min) + min;
}

Ответ 10

rand() вернет числа от 0 до RAND_MAX, что составляет не менее 32767.

Если вы хотите получить число в пределах диапазона, вы можете просто использовать modulo.

int value = rand() % 66; // 0-65

Для большей точности ознакомьтесь с этой статьей. В нем обсуждается, почему modulo не обязательно хорош (плохие дистрибутивы, особенно на высоком конце), и предоставляет различные варианты.

Ответ 11

Этот ответ фокусируется не на случайности, а на арифметическом порядке. Чтобы получить число в диапазоне, обычно мы можем сделать это так:

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

Ответ 12

Я думаю, что следующее полу справа. Прошло некоторое время с тех пор, как я коснулся 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);

Ответ 13

Если вы заботитесь о качестве ваших случайных чисел, не используйте rand()

используйте другие prng, такие как http://en.wikipedia.org/wiki/Mersenne_twister или один из других высококачественных prng там

тогда просто двигайтесь с модулем.

Ответ 14

Просто чтобы добавить некоторые дополнительные детали к существующим ответам.

Операция 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()

Ответ 15

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

Ответ 16

Простое использование 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 - минимальный_номер) + минимальный_номер

Надеюсь, поможет!

Ответ 17

Вы можете изменить его, добавив% перед функцией rand, чтобы перейти к коду

Например:

rand() % 50

даст вам случайное число в диапазоне от 50. Для вас замените 50 на 63 или 127

Ответ 18

Или вы можете использовать это:

rand() / RAND_MAX * 65

Но я не уверен, что это самый случайный или самый быстрый из всех ответов здесь.