This genertor is posted for informational purposes only. It has some unnice properties which make it unsuitable for some purposes.



/* 
 ULTRA
 This is a version of ULTRA,  a generator that was posted on the net
 a few years ago.  It combines the lagged Fibonacci generator
        x(n)=x(n-99)*x(n-33)  mod 2^32, x's odd
 with the multiply-with-carry generator
        y(n)=30903*y(n-1)+carry mod 2^16,
 returning x(n)+y(n) mod 2^32.
 By itself, the lagged Fibonacci generator using multiplication
 passes all tests except those dependent on the last bit, since
 the output integers are always odd.  Adding the MWC sequence
 provides a proper mix of trailing bits. The resulting combination
 in ULTRA seems to pass all tests and has a very long period.
 That period is  3*2^96*(30903*2^15-1),  about 2^127.5

*/

/* Initialized data */
#define ulong unsigned long

static int ultra_r = 17;
static int ultra_s = 5;
static ulong ultra_mwcs = 15;
static ulong ultra_juni;
static ulong ultra_ju[17] = {
     364541503,3961085081,3414663911,2762688119,2540080365,
    3733059389, 367198775, 362576243,1637345271,2107418755,
    2273955929, 352233113, 301124023, 410255677,4217379025,
    1341101751,3534999107
};


void seed_rand_ultra(ulong seed) {
    ulong i, j, k, l, js;
    int ii;

    i = seed|1;
    j = seed|2;
    k = seed|4;
    l = seed|8;

    ultra_mwcs = i + j + k + l;

    for (ii = 0; ii < 17; ++ii) {
        i = (i & 65535) * 18273 + (i >> 16);
        j = (j & 65535) * 23163 + (j >> 16);
        k = (k & 65535) * 24984 + (k >> 16);
        l = (l & 65535) * 28854 + (l >> 16);
        js = (i << 16) + (j & 65535) + (k << 16) + (l & 65535);
        js |= 1;
        ultra_ju[ii] = js;
    }
    ultra_r = 17;
    ultra_s = 5;
}

ulong rand_ultra(void)
{
    ultra_juni = ultra_ju[ultra_r] * ultra_ju[ultra_s];
    ultra_ju[ultra_r] = ultra_juni;
    if (ultra_r == 0) {
        ultra_r = 17;
    }
    --ultra_r;
    if (ultra_s == 0) {
        ultra_s = 17;
    }
    --ultra_s;
    ultra_mwcs = (ultra_mwcs & 65535) * 30903 + (ultra_mwcs >> 16);

    return ultra_juni + ultra_mwcs;
}