Issue:
System.Random is obviously pseudo random but works reasonably well.... or DOES it?
When my server runs for long enough (regardless of sharing a single static Random or even if I test by re-setting the random each time it's called) it starts just throwing out junk numbers.
Example:
Code:
public static int RandomNext(int maxVal)
{
var v = RND.Next( maxVal);
if (v > maxVal)
{
Console.WriteLine("Resetting random seed!! (Past Max)");
RND = new Random();
v = RND.Next(maxVal);
}
if (v == 0)
{
nullValues++;
if (nullValues > 5)
{
Console.WriteLine("Resetting random seed!! (Too many Zeros)");
RND = new Random();
v = RND.Next(maxVal);
nullValues = 0;
}
}
else
nullValues = 0;
return v;
}
In virtually ALL of my calls of this code I'm rolling a 100,000 value (percent success accurate to 3 decimal places).
This runs perfectly fine for a very long time... but eventually we start getting zeros thrown almost every time.
I've tried various quick fixes including resetting the random seed, ALWAYS returning from a new random class instead of all these sanity checks... hell we tried reverse engineering tq's own random class from the eudemons source.
No matter what, we always eventually end up with junk values being returned.
Note: Here's our test implementation of tq's random class... I don't consider it that special as anyone could download their source and reverse it damn easy.
Code:
public static int RandGet(int max, bool reset = false)
{
if (reset) _randomSeed = UnixTimestamp;
long x = 0xffffffff;
double i;
long final;
_randomSeed *= 134775813L;
_randomSeed += 1;
_randomSeed = Math.Abs(_randomSeed);
_randomSeed = _randomSeed % x;
i = _randomSeed / (double)0xffffffff;
if (i > 1)
{
Console.WriteLine("\r\r\r\tReturned Number: " + (long)(max * i) + " where max is: " + max + " Seed state of " + _randomSeed + " i value: " + i +"\r\r");
}
final = (long)(max * i);
if (final > max)
{
Console.WriteLine("\r\r\r\tReturned Number: " + final + " where max is: " + max + " Seed state of " + _randomSeed + " i value: " + i+"\r\r\r");
Console.WriteLine("ERROR! Invalid number thrown from call stack:");
Console.WriteLine(Environment.StackTrace.ToString());
final = new Random().Next(max);
_randomSeed = UnixTimestamp;
}
return (int)final;
}
What's interesting here is... it works perfectly fine if we try to do massive numbers of iterations (I think most we tested was 100 million in a row without issue)... again if we let it run over TIME (day or so) it starts to return complete garbage (greater than max)
Some examples of junk data being returned...
Returned: 17867370611
Max #: 14
Seed: 3998188691
Value of i: 1276240757.9309
Returned: 4063877655
Max #: 150
Seed: 1023408433
Value of i: 27092485.5720175
So yah... looking for options and also just scratching my head going "wtf" (at the system random, I expected nothing much from a basic reverse engineered tq random generator lol).
What would be causing System.Random to start returning zeros virtually every time we call it when the maxvalue entered was greater than 1 (and most often 100,000)
<edit>
After talking to korv I'm gonna try doing it so that if it returns junk too many times I set the random seed using tq's random generator (cause even if it returns greater then max value, it's still a random seed not related to computer time which I'm fairly sure must be the issue)
Side question. Does Random() by default use Environment.Tickcount to set its seed? A few seconds on google just said it was related to the computer time so I'm fairly sure it is... just curious though.







