copx said:
Can anyone point me to a simple, fast RRNG function to generate random
ints within a specified range? It is important that each value within the
range has the same probability (uniform distribution).
I do not want to use the unreliable rand() function, but I do not want to
bloat my code with something as complex as MT either. I am just looking
for a short code snippet that I can copy without worrying about licensing.
The function should work on limited platforms (no floating-point math
please, one that works even on platforms where int is only 16 bit would be
perfect).
I did search this group and the web but I could not find anything which
meets the requirements.
/* initialize with any 32-bit seed x and any 32-bit y not 0 */
static unsigned long x=2282008, y=362436069;
#define sK ( x=69069*x+123, y^=y<<13, y^=y>>17, y^=y<<5, x+y )
/* example main() should generate 10^9 integers in ~5 seconds,
with final j=1105441147. Try it.
*/
#include <stdio.h>
int main()
{unsigned long i,j;
for(i=0;i<1000000000;i++) j=sK;
printf("%U\n",j);
}
------------------- C code ends ------------------------
Use of sK in any expression will produce a random 32-bit integer,
(unsigned), so that, for example, u=sK*2.328306437e-10 will
produce a uniform real u in the interval [0,1),
while I=sK*f will produce an integer I from 0 to n-1
if f=n*2.328306437e-10.
If float operations must be avoided, and you want a random integer
from 0 to n-1, you can mask off bits after invoking sK, so that enough
remain to provide your integer, rejecting those outside the range.
For example, a random integer k in 0<=k<12345 needs 14 bits,
so generate
k=(sK>>18);
and keep those for which k<12345.
The inline sK returns x+y. The congruential x=69069*x+123
is chosen because the multiplier is easy to remember and
produces a good lattice in studying "random numbers fall
mainly in the planes", the Marsaglia effect. (123 can be any odd integer).
The xorshift y^=y<<13, y^=y>>17, y^=y<<5,
uses shifts 13,17,5 from the 648 available in the article Xorshift RNGs,
http://www.jstatsoft.org/v08/i14/paper
Here, sK stands for simple KISS, one of a class I call KISS RNGs,
based on the principle: Keep It Simple, Stupid.
sK should provide around 200 million random integers per second,
period about 2^64 and pass all the tests in Diehard,
http://i.cs.hku.hk/~diehard/
Other KISS versions combine three simple methods to produce 32-bit integer
sequences with periods 2^125, 2^993, 2^5147, 2^12153 or 2^31311,
or a dKISS version produces double precision, IEEE754 standard,
uniform [0,1) reals using only + /- float operations,
period exceeding 2^1748.
Send requests if interested.
George Marsaglia