Skip to content

Instantly share code, notes, and snippets.

@sakiraykurt
Created March 8, 2022 19:19
Show Gist options
  • Save sakiraykurt/59d000c17b04415d3953929f13b43360 to your computer and use it in GitHub Desktop.
Save sakiraykurt/59d000c17b04415d3953929f13b43360 to your computer and use it in GitHub Desktop.
C# random class which is 'Lehmer RNG' formula based.
//See: https://en.wikipedia.org/wiki/Linear_congruential_generator
//See: https://en.wikipedia.org/wiki/Lehmer_random_number_generator
public class Random
{
private const int m = 65537; // (2 ^ 16) + 1, a Fermat prime
private const int a = 75; // a Primitive root modulo
private const int x0 = 65536; // Number, greater than '0', less than 'm'
private static int ox, cx; // Original seed, Current seed
private static readonly float md; // floating-point devider
// Creates a constructor of random class
static Random()
{
ox = x0;
cx = x0;
md = m - 1;
}
// Lehmer random number generator formula
private static int RNG(int x)
{
return (x * a) % m;
}
// Random min-max number formula
private static int RMM(int min, int max, int x)
{
return min + (x % (max - min));
}
// Random min-max number formula
private static float RMM(float min, float max, float x)
{
return min + ((max - min) * x);
}
// Checks seed number is valid
private static bool IV(int n)
{
if ((n <= 0) && (n >= m))
throw new System.ArgumentException("Invalid seed number!");
if (n % 1 != 0)
throw new System.ArgumentException("Seed number should be an integer!");
return true;
}
/// <summary>
/// Get or Set a random seed number.
/// </summary>
public static int Seed
{
get => ox;
set
{
IV(value);
ox = value;
cx = value;
}
}
/// <summary>
/// Returns a random integer number between [min, max).
/// </summary>
/// <param name="min"></param>
/// <param name="max"></param>
/// <returns>Integer number</returns>
public static int Range(int min, int max)
{
if (min > max)
throw new System.ArgumentOutOfRangeException("Invalid 'min'-'max' values");
cx = RNG(cx);
return RMM(min, max, cx);
}
/// <summary>
/// Returns a random floating-point number between [min, max]
/// </summary>
/// <param name="min"></param>
/// <param name="max"></param>
/// <returns>Float number</returns>
public static float Range(float min, float max)
{
if (min > max)
throw new System.ArgumentOutOfRangeException("Invalid 'min'-'max' values");
cx = RNG(cx);
return RMM(min, max, RMM(0, m, cx) / md);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment