-5

I'm trying (as a bungler noob) to use this alghoritm to generate random numbers

/* initialize state to random bits */
static unsigned long state[16];
/* init should also reset this to 0 */
static unsigned int index = 0;
/* return 32 bit random number */
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)&0xDA442D20UL);
index = (index + 15)&15;
a = state[index];
state[index] = a^b^d^(a<<2)^(b<<18)^(c<<28);
return state[index];
}

But it seems not to work (result every time 0). I found it here What is a good random number generator for a game? in the comments there is one that say "I waste one evening to understand why my code doesn't work: on 64 bit machines this code procude 64 bit number! Use sizeof(unsigned long) * 8". I have a 64bit sistem but I don't understand what I have to do! It's surely better that I use stdlib.

Community
  • 1
  • 1
The Newbie Toad
  • 186
  • 2
  • 15
  • 5
    as a general rule, you should never use code from an outside source that you yourself do not understand. Its a sure-fire way to add unforeseeable bugs to your program, even if the excerpt you copied works. – Daboyzuk Apr 22 '13 at 08:44
  • Seconded, @Daboyzuk. In C++ if you run code that you don't understand, you are giving somebody else full access to the bare metal of your machine. This opens your machine up to a world of hurt. – Glitch Desire Apr 22 '13 at 08:45
  • I asked in a comment where that phrase should be used. Make sure you check back and see if/when the original commenter replies. – Shahbaz Apr 22 '13 at 08:45
  • 1
    The constant should be (according to original paper): 0xDA442D24UL – Mitch Wheat Apr 22 '13 at 08:48
  • 2
    @TommasoFerrari: How about using the standard library until you are proficient enough to make use of third-party code? – DevSolar Apr 22 '13 at 08:48
  • @TommasoFerrari If you dont understand how this code works, you have 3 options. 1) Research it, and learn how the code works/make one yourself 2) use something simpler that you DO understand 3) use a 3rd party library that can do it for you. – Daboyzuk Apr 22 '13 at 08:50
  • If you have access to a type like `uint32_t`, use it instead of `unsigned long`. – UmNyobe Apr 22 '13 at 08:51
  • @DevSolar What can I find in the standard library? I tried with rand() but I need more than one number in the same time (bethween 0 and 1) and rand() doesn't give it. – The Newbie Toad Apr 22 '13 at 08:55
  • @TommasoFerrari: `rand()` will give you as many numbers as you want, just call it repeatedly. Do NOT call `srand()` repeatedly. – MSalters Apr 22 '13 at 08:58
  • @MSalters thank you! I think it's ok enought, although the first number generated is always nearly the same (I can understand why); – The Newbie Toad Apr 22 '13 at 09:13

1 Answers1

0

Edit: Original supposition on the problem completely wrong. The cause of you getting all zeros is that the state is not seeded. You need to fill state with something 'random'.

This code work. Note that the function seed() is in absolutely no way scientifically proven to be good - in fact, I just made it up as I went along, trying to get as much "bits" as possible varying as much as possible in the seed. You should do some research on "seeding random numbers". (I also tried seeding with just state[i] = i;, and that also seems to work fairly well, but you get quite similar numbers in the first couple of iterations).

#include <iostream>
#include <cstdint>

/* initialize state to random bits */
static uint32_t state[16];
/* init should also reset this to 0 */
static unsigned int index = 0;
/* return 32 bit random number */
uint32_t WELLRNG512(void)
{
    uint32_t 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];
}

void seed()
{
    for(size_t i = 0; i < sizeof(state)/sizeof(state[0]); i++)
    {
    state[i] = (i << (24 + (i & 5))) ^ (i << 7) ^ (i << 6) ^ (i >> 2);
    }
}    

int main()
{
    using namespace std;
    seed();
    for(int i = 0; i < 50; i++)
    {
    cout << WELLRNG512() << endl;
    }
    return 0;
}
Mats Petersson
  • 126,704
  • 14
  • 140
  • 227