document the Random class
parent
35934baec0
commit
3a7c9da309
|
@ -3,8 +3,10 @@ using System.Runtime.CompilerServices;
|
|||
|
||||
namespace MoonTools.ECS
|
||||
{
|
||||
// WELLRNG512
|
||||
// https://stackoverflow.com/a/1227137
|
||||
/// <summary>
|
||||
/// This class implements the well equidistributed long-period linear pseudorandom number generator.
|
||||
/// Code taken from Chris Lomont: http://lomont.org/papers/2008/Lomont_PRNG_2008.pdf
|
||||
/// </summary>
|
||||
public class Random
|
||||
{
|
||||
public const int STATE_BYTE_COUNT = 68; // 16 state ints + 1 index int
|
||||
|
@ -13,11 +15,17 @@ namespace MoonTools.ECS
|
|||
uint Index = 0;
|
||||
uint Seed;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the RNG with an arbitrary seed.
|
||||
/// </summary>
|
||||
public Random()
|
||||
{
|
||||
Init((uint) Environment.TickCount);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the RNG with a given seed.
|
||||
/// </summary>
|
||||
public void Init(uint seed)
|
||||
{
|
||||
Seed = seed;
|
||||
|
@ -30,11 +38,17 @@ namespace MoonTools.ECS
|
|||
Index = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the seed that was used to initialize the RNG.
|
||||
/// </summary>
|
||||
public uint GetSeed()
|
||||
{
|
||||
return Seed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the entire state of the RNG as a string.
|
||||
/// </summary>
|
||||
public string PrintState()
|
||||
{
|
||||
var s = "";
|
||||
|
@ -46,7 +60,11 @@ namespace MoonTools.ECS
|
|||
return s;
|
||||
}
|
||||
|
||||
// expects a span of STATE_BYTE_COUNT bytes
|
||||
/// <summary>
|
||||
/// Saves the entire state of the RNG to a Span.
|
||||
/// </summary>
|
||||
/// <param name="bytes">Must be a span of at least STATE_BYTE_COUNT bytes.</param>
|
||||
/// <exception cref="ArgumentException">Thrown if the byte span is too short.</exception>
|
||||
public unsafe void SaveState(Span<byte> bytes)
|
||||
{
|
||||
#if DEBUG
|
||||
|
@ -69,7 +87,11 @@ namespace MoonTools.ECS
|
|||
}
|
||||
}
|
||||
|
||||
// expects a span of STATE_BYTE_COUNT bytes
|
||||
/// <summary>
|
||||
/// Loads the entire state of the RNG from a Span.
|
||||
/// </summary>
|
||||
/// <param name="bytes">Must be a span of at least STATE_BYTE_COUNT bytes.</param>
|
||||
/// <exception cref="ArgumentException">Thrown if the byte span is too short.</exception>
|
||||
public unsafe void LoadState(Span<byte> bytes)
|
||||
{
|
||||
#if DEBUG
|
||||
|
@ -109,17 +131,25 @@ namespace MoonTools.ECS
|
|||
return State[Index];
|
||||
}
|
||||
|
||||
// .NET Random API always returns a non-negative signed int. Fun!
|
||||
/// <summary>
|
||||
/// Returns a non-negative signed integer.
|
||||
/// </summary>
|
||||
public int Next()
|
||||
{
|
||||
return (int) (NextInternal() >>> 1); // unsigned bitshift right to get rid of signed bit
|
||||
}
|
||||
|
||||
public int Next(int n)
|
||||
/// <summary>
|
||||
/// Returns a non-negative signed integer less than max.
|
||||
/// </summary>
|
||||
public int Next(int max)
|
||||
{
|
||||
return (int) (((double) Next()) * n / int.MaxValue);
|
||||
return (int) (((double) Next()) * max / int.MaxValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a signed integer greater than or equal to min and less than max.
|
||||
/// </summary>
|
||||
public int Next(int min, int max)
|
||||
{
|
||||
var diff = max - min;
|
||||
|
@ -127,6 +157,9 @@ namespace MoonTools.ECS
|
|||
return min + next;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a non-negative signed 64 bit integer.
|
||||
/// </summary>
|
||||
public long NextInt64()
|
||||
{
|
||||
long next = NextInternal();
|
||||
|
@ -136,12 +169,18 @@ namespace MoonTools.ECS
|
|||
return next;
|
||||
}
|
||||
|
||||
public long NextInt64(long n)
|
||||
/// <summary>
|
||||
/// Returns a non-negative signed 64 bit integer less than max.
|
||||
/// </summary>
|
||||
public long NextInt64(long max)
|
||||
{
|
||||
var next = NextInt64();
|
||||
return (long) (((double) next) * n / long.MaxValue);
|
||||
return (long) (((double) next) * max / long.MaxValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a non-negative signed 64 bit integer greater than or equal to min and less than max.
|
||||
/// </summary>
|
||||
public long NextInt64(long min, long max)
|
||||
{
|
||||
var diff = max - min;
|
||||
|
@ -149,12 +188,18 @@ namespace MoonTools.ECS
|
|||
return min + next;
|
||||
}
|
||||
|
||||
public float NextFloat()
|
||||
/// <summary>
|
||||
/// Returns a single-precision floating point value between 0 and 1.
|
||||
/// </summary>
|
||||
public float NextSingle()
|
||||
{
|
||||
var n = NextInternal();
|
||||
return ((float) n) / uint.MaxValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a double-precision floating point value between 0 and 1.
|
||||
/// </summary>
|
||||
public double NextDouble()
|
||||
{
|
||||
var n = NextInternal();
|
||||
|
|
Loading…
Reference in New Issue