О rand () в c - PullRequest
       33

О rand () в c

0 голосов
/ 31 октября 2019

q1)

Является ли эта реализация rand () и srand ():

  • правильной?
  • используемой наиболее популярными реализациями?
  • требуется стандартом?
unsigned int __seed;

void srand(unsigned int s) {
    __seed = s;
}

int rand() {
    __seed = __deterministic_and_fast_mathematical_expression_that_depend_only_of_seed(__seed); // Call it expr(), Declared somewhere
    return __seed;
}

q2)

Тогда, если q1) верно (или по-другому), верно ли говорить, что существуетциклы в такой функции, что rand () можно интерпретировать как циклическую последовательность, заданную в случайной точке?

// Hypotetically
srand(a)
if rand() = b then expr(a) = b
if rand() = a then expr(b) = a
// Then any call to rand would give successively [a, b, a, b, a, ...] infinitely
// This example is for two values but can work for a sequence of any length

Я предполагаю, что функция rand () является циклической после максимум 2 ^ 64 итераций на64 бита и 2 ^ 32 на 32 бита. Например, если где-то в последовательности есть:

12891, 872821, 33, 872821, 33, 872821, ... Infinitely

Мы можем изолировать деталь 33, 872821 и деталь до и сделать стрелку от второго до первого. Тогда функция ранда может быть описана этим графиком, сгенерированным этой процедурой:

for(int i = 0; i < RAND_MAX; i++) {
    srand(i);
    while(rand() != i);
    // ISolate the cycle for seed = i
}

q3)

Если q2) истинно (или другим способом), как мы можем гарантировать, чтоэта функция не выдаст «разбитую» последовательность с повторениями или очень мало, или просто она не указана?

q4)

Можем ли мы узнать, какое начальное число предшествует последовательности?

Ответы [ 3 ]

2 голосов
/ 31 октября 2019

В соответствии с спецификацией Unix C стандартом ), rand() будет генерировать последовательность псевдослучайных чисел с периодом не менее 2 ^ 32.

Функция rand () вычисляет последовательность псевдослучайных целых чисел в диапазоне от 0 до {RAND_MAX} с периодом не менее 2 ^ 32.

Это означает, чтоон не будет повторять одну и ту же последовательность чисел, пока не достигнет 2 ^ 32 сгенерированных чисел. Что касается вашего первого вопроса, он является детерминированным, так как одно и то же начальное число, данное rand(), будет каждый раз производить одну и ту же последовательность.

2 голосов
/ 31 октября 2019

1) правильно? да
требуется? нет конкретных требований. качество сгенерированных чисел является вопросом «качества реализации»

2) в стандарте нет требований, за исключением повторяемости

3) качества реализации

4) качество исполнения

1 голос
/ 01 ноября 2019

q1) Является ли эта реализация rand () и srand (): правильной?

Я бы сказал, нет.
* Код определенно не ограничивает диапазон rand() до [0...INT_MAX]. @ Флюгер . return __seed & INT_MAX решит это.
* Незарезервированный идентификатор __seed - это нет-нет. C17dr 7.1.3 1. Я бы ожидал, что static unsigned __seed ограничит область.
* Для пользователя, сделавшего rand(),srand(), я бы также ожидал определение RAND_MAX.

q1) Является ли эта реализация rand () и srand (): используемой самыми популярными реализациями?

Сомнительно. IAC, «наиболее популярные» реализации субъективны. Производятся миллиарды встроенных процессоров в год, и их популярность и небольшая площадь могут исказить идею «самой популярной» реализации. Я не вижу никакого преимущества, если предположить такую ​​реализацию, кроме как использовать слабый rand(). Я ожидаю, что большинство реализаций будет стремиться использовать более широкое состояние, чем начальное число. **

q1) Является ли эта реализация rand () и srand (): требуетсястандарт?

Нет. Стандарт довольно открытый.


** Хотя начальное значение ограничено unsigned, скажем, 32-битным, переменная состояния может быть намного шире - возможно, сотнибит. Конечно, это означает, что все состояния не могут быть начальными точками.

srand() начальное число также может в основном игнорироваться. Когда я читаю спецификацию, нет необходимости использовать все биты начального числа.

Качество srand(), rand() может быть большим или слабым - такой же маленький диапазон, как [0...32767] и, возможно, цикл, которыйтоже маленький.

q4) Можем ли мы выяснить, какое семя предшествует последовательности?

Грубая сила приходит на ум - попробуйте много семян. По спецификации, та же самая начальная точка будет генерировать ту же самую выходную последовательность rand() для реализации , что и реализация . Кроме этого, не указан способ. Обратите внимание, что желаемое начальное число может не существовать для достижения выбранной последовательности rand() из начального числа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...