Реализация WELLRNG512

Я видел много постов о WELLRNG512. Предположительно, я пришел к выводу, что это был бы лучший выбор, чем Mersenne Twister для roguelike crawler. Я пытаюсь заставить этот кусок кода генерировать случайные числа и вести себя так же, как rand().

Используемый код:

static unsigned long state[16];
static unsigned int index = 0;

int main (void) {
    int i;

    for (i = 0; i < 16; i++) {
        index = i;
        printf("random: %lu\n", WELLRNG512());
    }

    return 0;
}

unsigned long WELLRNG512 (void) {
    unsigned long a, b, c, d;

    a = state[index];
    c = state[(index+13)&15];
    b = a^c^(a<<16)^(c<<15);
    c = state[(index+9)&15];
    c ^= (c>>11);
    a = state[index] = b^c;
    d = a^((a<<5)&0xDA442D24UL);
    index = (index + 15)&15;
    a = state[index];
    state[index] = a^b^d^(a<<2)^(b<<18)^(c<<28);

    return state[index];
}

Ожидаемые результаты:

random: 231544
random: 542312
random: 588690
(...etc...)

Полученные результаты:

random: 4195755
random: 4195755
random: 4195755
(...etc...)

Кто-нибудь понял, как я могу успешно заставить этот кусок кода вести себя как rand ()?

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

1 ответ

Решение

Есть некоторые вещи не так с кодом. Самый важный: вы никогда не вызываете генератор случайных чисел. Эта строка здесь:

   printf("random: %lu\n", WELLRNG512);

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

   printf("random: %lu\n", WELLRNG512());

Второе: массив состояний должен быть заполнен случайными данными. Просто для тестирования я бросил что-то вместе на основе функции rand(). Это может быть или не быть умным способом заполнения массива состояний, но этого достаточно, чтобы получить некоторые случайные данные из вашей функции.

/* seed the state array */
for (i = 0; i < 16; i++)
  state[i] = rand()^(rand()<<16)^(rand()<<31);

Последнее: функция WELLRNG512 сама увеличивает индексную переменную. Нет необходимости делать это в цикле тестирования, который находится в main.

Моя полная основная функция выглядит так:

int main (void) {
    int i;

    /* seed */
    for (i = 0; i < 16; i++)
      state[i] = rand()^(rand()<<16)^(rand()<<31);

    for (i = 0; i < 16; i++) {
        printf("random: %lu\n", WELLRNG512());
    }

    return 0;
}

Это должно исправить ваши проблемы.

Другие вопросы по тегам