gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

C/C++ > random numbers

#12135 - ken2 - Fri Oct 31, 2003 7:43 am

I seem to have forgotten how to code random numbers between 0 and 20. Like how to pick a random # from between those two and set it to a variable.

#12136 - Datch - Fri Oct 31, 2003 2:35 pm

From the FAQ :

Q: How do I generate pseudo-random numbers?
See the topics linked from here.
_________________
Visit SR-388 now and get a 40% discount!

#12156 - ken2 - Sat Nov 01, 2003 2:41 am

hmmm, my code doesnt seem to be working, any suggestions?

unsigned long seed;

signed long dice(signed long min, signed long max)
{
seed *= 69069;
return min + ((max - min + 1) * (seed >> 16)) / 0x10000;
}


void Xyset()
{
xpos2 = dice(5,100);

if (ypos2<115){
ypos2++;
}
else
{
ypos2 = 10;
}
}

#12157 - Burton Radons - Sat Nov 01, 2003 3:37 am

That'll never return anything but zero. Try:

Code:

unsigned long seed = 289301;

signed long dice(signed long min, signed long max)
{
   seed = seed * 69069 + 1;
   return min + ((max - min + 1) * (seed >> 16)) / 0x10000;
}

#12607 - sgeos - Wed Nov 19, 2003 9:02 am

That RNG looks like something I could have written. =P Did you remember to seed the RNG? You could set it to any non zero value...

seed = 0x12459FE8;

Or, if you want to make things really fancy, start up a timer and seed the RNG using the value in the timer.

Code:
start_timer();
wait_for_input();
seed = get_timer_state();


-Brendan

#12615 - dagamer34 - Wed Nov 19, 2003 5:52 pm

There is always the rand () function. That has always worked for me.
num = rand () % 20;
_________________
Little kids and Playstation 2's don't mix. :(

#12618 - Touchstone - Wed Nov 19, 2003 6:36 pm

dagamer34 wrote:
There is always the rand () function. That has always worked for me.
num = rand () % 20;

Actually, there's not always the rand() function since it's a part of stdlib and you don't always have that. Beware, if you pay attention to me I might have to zap your brain!
_________________
You can't beat our meat

#12619 - tom - Wed Nov 19, 2003 6:39 pm

sure rand() works fine, is useful and all, it's just awfully slow =)

#12630 - sgeos - Thu Nov 20, 2003 12:14 am

dagamer34 wrote:
There is always the rand () function. That has always worked for me.
num = rand () % 20;


Have you read the man page for rand? Using mod is a bad way of doing things. It uses the low order bits of the RNG. rand() is is a LCG in many implementations. Depending on the LCG, bit zero of the RNG state may always be the same!

The code posted above:
state *= 69069;
Or
state = state * 69069 + 1;
Are both LCGs.

BTW, does adding one affect the period of the generator? If so, is it affected in a positive or negative way?

-Brendan

#12642 - tom - Thu Nov 20, 2003 8:23 am

sgeos wrote:
The code posted above:
state *= 69069;
Or
state = state * 69069 + 1;
Are both LCGs.

BTW, does adding one affect the period of the generator? If so, is it affected in a positive or negative way?


i think the +1 is to keep the generator from returning only 0, should state become 0. so if you look at it this way, it does affect the period of the rng in a positive way, yes =)

#12643 - sgeos - Thu Nov 20, 2003 9:07 am

tom wrote:
i think the +1 is to keep the generator from returning only 0, should state become 0. so if you look at it this way, it does affect the period of the rng in a positive way, yes =)


Clearly the intent is to keep the generator from returning zero. If that is the goal, I'd advise ORing the state with 0x1 or seeding the RNG with an odd number. I can state with 100% certainty that the state will never be zero if the current state is odd, and the LCG's multiplier (69069 in this case) is odd.

Adding 1 wastes a cycle (probably not important) and it may destroy the mathematic properties of this particular generator. I highly doubt that it does, even if the period (number of calls to the RNG until you get back to where you started) were cut by a factor of ten it would still probably be long enough.

My point is, be careful. RNGs are hard to write and easy to break if you don't know what you are doing. The state *= 69069 deal was adapted from an older version of the mersenne twister source code. That code mentioned Knuth, and it may have originated from somewhere in Volume II of the Art of Computer Programming.

-Brendan