Link to home
Start Free TrialLog in
Avatar of publicvoid
publicvoidFlag for United States of America

asked on

Picking a random number between x and y using the KISS generator by George Marsaglia

Ok this is c++ code, but I am going to port it over.  In the mean time, if i have this code that generates pretty good random numbers, how do i restrict its output to a certain range (ie 0-500000) without weighting the results either way.  Should i just keep picking random number until i get one in the range that i want and then return it?  Or is there a better way?  Here is the c++ code:  (Again i am moving this to c#, so any help in that direction would be great also)

#include <stdio.h>
#define znew (z=36969*(z&65535)+(z>>16))
#define wnew (w=18000*(w&65535)+(w>>16))
#define MWC ((znew<<16)+wnew )
#define SHR3 (jsr^=(jsr<<17), jsr^=(jsr>>13), jsr^=(jsr<<5))
#define CONG (jcong=69069*jcong+1234567)
#define FIB ((b=a+b),(a=b-a))
#define KISS ((MWC^CONG)+SHR3)
#define LFIB4 (c++,t[c]=t[c]+t[UC(c+58)]+t[UC(c+119)]+t[UC(c+178)])
#define SWB (c++,bro=(x<y),t[c]=(x=t[UC(c+34)])-(y=t[UC(c+19)]+bro))
#define UNI (KISS*2.328306e-10)
#define VNI ((long) KISS)*4.656613e-10
#define UC (unsigned char) /*a cast operation*/
typedef unsigned long UL;
/* Global static variables: */
static UL z=362436069, w=521288629, jsr=123456789, jcong=380116160;
static UL a=224466889, b=7584631, t[256];
/* Use random seeds to reset z,w,jsr,jcong,a,b, and the table
t[256]*/
static UL x=0,y=0,bro; static unsigned char c=0;
/* Example procedure to set the table, using KISS: */
void settable(UL i1,UL i2,UL i3,UL i4,UL i5, UL i6)
{ int i; z=i1;w=i2,jsr=i3; jcong=i4; a=i5; b=i6;
for(i=0;i<256;i=i+1) t[i]=KISS;
}
/* This is a test main program. It should compile and print 7
0's. */
int main(void){
int i; UL k;
settable(12345,65435,34221,12345,9983651,95746118);
for(i=1;i<1000001;i++){k=LFIB4;} printf("%u\n", k-1064612766U);
for(i=1;i<1000001;i++){k=SWB ;} printf("%u\n", k- 627749721U);
for(i=1;i<1000001;i++){k=KISS ;} printf("%u\n", k-1372460312U);
for(i=1;i<1000001;i++){k=CONG ;} printf("%u\n", k-1529210297U);
for(i=1;i<1000001;i++){k=SHR3 ;} printf("%u\n", k-2642725982U);
for(i=1;i<1000001;i++){k=MWC ;} printf("%u\n", k- 904977562U);
for(i=1;i<1000001;i++){k=FIB ;} printf("%u\n", k-3519793928U);
}


http://www.cs.yorku.ca/~oz/marsaglia-rng.html is the website where this was found.  It has notes on the end that i did not include here to keep this post from being too long.  It explains that the UNI generator does this:

   Finally, because many simulations call for uniform
   random variables in 0<x<1 or -1<x<1, I use #define
   statements that permit inclusion of such variates
   directly in expressions: using UNI will provide a
   uniform random real (float) in (0,1), while VNI will
   provide one in (-1,1).


I will be using the UNI(KISS) generator in the above code.

Thank you,
John Gjonola
Avatar of jatinderalagh
jatinderalagh
Flag of India image

Why don't you use the Random class with in FrameWork library

It's using System.Random namespace

 // Generate random numbers with both bounds specified.
    static void BothBoundsRandoms( int seed, int lower, int upper )
    {
        Console.WriteLine(
            "\nRandom object, seed = {0}, lower = {1}, " +
            "upper = {2}:", seed, lower, upper );
        Random randObj = new Random( seed );

        // Generate six random integers from the lower to
        // upper bounds.
        for( int j = 0; j < 6; j++ )
            Console.Write( "{0,11} ",
                randObj.Next( lower, upper) );
        Console.WriteLine( );
    }
Avatar of publicvoid

ASKER

Thanks but no go...  Due to certain regulations the random number generator has to pass certain tests, and the one built into .net doesn't pass.  

Thank you,
John Gjonola
ASKER CERTIFIED SOLUTION
Avatar of gregoryyoung
gregoryyoung
Flag of Canada image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Nice!  Love the mersenne twister.  That passes the test.  Thank you so much!

John Gjonola
I personally use MT in my chess engine (zobrist hash) and have always had pretty good results from it.

Greg