实施WELLRNG512

时间:2014-02-02 20:39:51

标签: c prng roguelike

我看过很多关于WELLRNG512的帖子。据说我已经得出结论,对于一个roguelike地牢爬行者来说,它比Mersenne Twister更好。我试图获得this段代码来生成随机数,其行为与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()一样?

P.S。:我是学生,绝对不是数学家,所以如果你打算使用任何类型的象形文字来解释公式等,请详细解释你的答案。

1 个答案:

答案 0 :(得分: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;
}

这应该可以解决你的问题。