Created
April 1, 2019 07:20
-
-
Save michel-pi/3853ad62dd02c99affc0b7439b7a6da0 to your computer and use it in GitHub Desktop.
A static and thread safe pseudo-random number generator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Threading; | |
namespace System | |
{ | |
/// <summary> | |
/// Represents a static and thread safe pseudo-random number generator, which is a device that produces a sequence of numbers that meet certain statistical requirements for randomness. | |
/// </summary> | |
public static class StaticRandom | |
{ | |
[ThreadStatic] private static int seed; | |
[ThreadStatic] private static Random random; | |
/// <summary> | |
/// Gets the value of the seed which was used when the pseudo-random number generator was initialized. | |
/// </summary> | |
public static int Seed | |
{ | |
get | |
{ | |
return seed; | |
} | |
} | |
/// <summary> | |
/// Returns a non-negative random integer. | |
/// </summary> | |
/// <returns>A 32-bit signed integer that is greater than or equal to 0 and less than <see cref="F:System.Int32.MaxValue" />.</returns> | |
public static int Next() | |
{ | |
if (random == null) random = GetRandomNumberGenerator(); | |
return random.Next(); | |
} | |
/// <summary> | |
/// Returns a non-negative random integer that is less than the specified maximum. | |
/// </summary> | |
/// <param name="maxValue">The exclusive upper bound of the random number to be generated. <paramref name="maxValue" /> must be greater than or equal to 0.</param> | |
/// <returns>A 32-bit signed integer that is greater than or equal to 0, and less than <paramref name="maxValue" />; that is, the range of return values ordinarily includes 0 but not <paramref name="maxValue" />. However, if <paramref name="maxValue" /> equals 0, <paramref name="maxValue" /> is returned.</returns> | |
/// <exception cref="T:System.ArgumentOutOfRangeException"><paramref name="maxValue" /> is less than 0. </exception> | |
public static int Next(int maxValue) | |
{ | |
if (random == null) random = GetRandomNumberGenerator(); | |
return random.Next(maxValue); | |
} | |
/// <summary> | |
/// Returns a random integer that is within a specified range. | |
/// </summary> | |
/// <param name="minValue">The inclusive lower bound of the random number returned.</param> | |
/// <param name="maxValue">The exclusive upper bound of the random number returned. <paramref name="maxValue" /> must be greater than or equal to <paramref name="minValue" />.</param> | |
/// <returns>A 32-bit signed integer greater than or equal to <paramref name="minValue" /> and less than <paramref name="maxValue" />; that is, the range of return values includes <paramref name="minValue" /> but not <paramref name="maxValue" />. If <paramref name="minValue" /> equals <paramref name="maxValue" />, <paramref name="minValue" /> is returned.</returns> | |
/// <exception cref="T:System.ArgumentOutOfRangeException"><paramref name="minValue" /> is greater than <paramref name="maxValue" />. </exception> | |
public static int Next(int minValue, int maxValue) | |
{ | |
if (random == null) random = GetRandomNumberGenerator(); | |
return random.Next(minValue, maxValue); | |
} | |
/// <summary> | |
/// Fills the elements of a specified array of bytes with random numbers. | |
/// </summary> | |
/// <param name="buffer">An array of bytes to contain random numbers.</param> | |
/// /// <exception cref="T:System.ArgumentNullException"><paramref name="buffer" /> is <see langword="null" />. </exception> | |
public static void NextBytes(byte[] buffer) | |
{ | |
if (random == null) random = GetRandomNumberGenerator(); | |
random.NextBytes(buffer); | |
} | |
/// <summary> | |
/// Returns a random boolean. | |
/// </summary> | |
/// <returns>A boolean value.</returns> | |
public static bool NextBool() | |
{ | |
return NextDouble() >= 0.5; | |
} | |
/// <summary> | |
/// Returns a random floating-point number that is greater than or equal to 0.0, and less than 1.0. | |
/// </summary> | |
/// <returns>A double-precision floating point number that is greater than or equal to 0.0, and less than 1.0.</returns> | |
public static double NextDouble() | |
{ | |
if (random == null) random = GetRandomNumberGenerator(); | |
return random.NextDouble(); | |
} | |
/// <summary> | |
/// Returns a random floating-point number that is greater than or equal to 0.0, and less than <paramref name="maxValue" />. | |
/// </summary> | |
/// <param name="maxValue">The exclusive upper bound of the random number returned.</param> | |
/// <returns>A double-precision floating point number that is greater than or equal to 0, and less than <paramref name="maxValue" />; that is, the range of return values ordinarily includes 0 but not <paramref name="maxValue" />.</returns> | |
public static double NextDouble(double maxValue) | |
{ | |
if (double.IsInfinity(maxValue) | |
|| double.IsNaN(maxValue) | |
|| maxValue < 1.0d) throw new ArgumentOutOfRangeException(nameof(maxValue)); | |
return NextDouble() * maxValue; | |
} | |
/// <summary> | |
/// Returns a random floating-point number that is within a specified range. | |
/// </summary> | |
/// <param name="minValue">The inclusive lower bound of the random number returned.</param> | |
/// <param name="maxValue">The exclusive upper bound of the random number returned.</param> | |
/// <returns>A double-precision floating point number that is greater than or equal to <paramref name="minValue" />, and less than <paramref name="maxValue" />; that is, the range of return values ordinarily includes 0 but not <paramref name="maxValue" />.</returns> | |
public static double NextDouble(double minValue, double maxValue) | |
{ | |
if (double.IsInfinity(minValue) | |
|| double.IsNaN(minValue) | |
|| minValue >= maxValue) throw new ArgumentOutOfRangeException(nameof(maxValue)); | |
if (double.IsInfinity(maxValue) | |
|| double.IsNaN(maxValue) | |
|| maxValue < 1.0d) throw new ArgumentOutOfRangeException(nameof(maxValue)); | |
return minValue + NextDouble() * (maxValue - minValue); | |
} | |
private static Random GetRandomNumberGenerator() | |
{ | |
seed = Environment.TickCount ^ ((Thread.CurrentThread.ManagedThreadId + 1) * 23); | |
return new Random(seed); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment