my MRG32k3a algorithm implementation is returning numbers outside of the intended [0,1] range

I’m writing my own implementation of the MRG32k3a algorithm and the returning value which is supposed to be from [0,1] returns values > 1

static double rand()
{
    double x = 0;

    long seed1 = DateTime.Now.Year;
    long seed2 = DateTime.Now.Month;
    long seed3 = DateTime.Now.Day;
    long seed4 = DateTime.Now.Hour;
    long seed5 = DateTime.Now.Minute;
    long seed6 = DateTime.Now.Second;

    long m1 = 4294967296 - 209;
    long m2 = 4294967296 - 22853;

    long A1 = ((1403580 * seed2) - (810728 * seed1)) % m1;
    long A2 = ((1403580 * seed3) - (810728 * seed2)) % m1;
    long Ai = ((1403580 * A2) - (810728 * A1)) % m1;

    long B1 = ((527612 * seed6) - (1370589 * seed4)) % m2;
    long B2 = ((527612 * B1) - (1370589 * seed5)) % m2;
    long B3 = ((527612 * B2) - (1370589 * seed6)) % m2;
    long Bi = ((527612 * B3) - (1370589 * B1)) % m2;

    if (Ai < Bi) { x = Ai - Bi + m1; }
    else if (Ai >= Bi) { x = Ai - Bi; }

    x = (x / m1);

    return x;
}

I tried multiple normalisation ideas, where I add, modulus with m1 and m2 and it led to nothing changing, similarly I tried to change the seeds to current ticks / previous seeds i.e. long seed1 = DateTime.Now.Ticks / DateTime.Now.Year and that changed the range from [0,1] to [-1,1]. I don’t know where to go from here to make it work as intended

Seems it’s better to use unsigned variables:

...
unchecked
{
    ulong A1 = ((1403580 * seed2) - (810728 * seed1)) % m1;
    ulong A2 = ((1403580 * seed3) - (810728 * seed2)) % m1;
    ulong Ai = ((1403580 * A2) - (810728 * A1)) % m1;

    ulong B1 = ((527612 * seed6) - (1370589 * seed4)) % m2;
    ulong B2 = ((527612 * B1) - (1370589 * seed5)) % m2;
    ulong B3 = ((527612 * B2) - (1370589 * seed6)) % m2;
    ulong Bi = ((527612 * B3) - (1370589 * B1)) % m2;    

    if (Ai < Bi) { x = Ai - Bi + m1; }
    else if (Ai >= Bi) { x = Ai - Bi; }

    x = (x / m1);

    return x;
}

Leave a Comment