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;
}