From 3a7c9da309d961dd69b84b620f71db6056414e0d Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Fri, 13 Oct 2023 13:18:14 -0700 Subject: [PATCH] document the Random class --- src/Random.cs | 65 +++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 55 insertions(+), 10 deletions(-) diff --git a/src/Random.cs b/src/Random.cs index 385bfb2..6f8b258 100644 --- a/src/Random.cs +++ b/src/Random.cs @@ -3,8 +3,10 @@ using System.Runtime.CompilerServices; namespace MoonTools.ECS { - // WELLRNG512 - // https://stackoverflow.com/a/1227137 + /// + /// 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 + /// 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; + /// + /// Initializes the RNG with an arbitrary seed. + /// public Random() { Init((uint) Environment.TickCount); } + /// + /// Initializes the RNG with a given seed. + /// public void Init(uint seed) { Seed = seed; @@ -30,11 +38,17 @@ namespace MoonTools.ECS Index = 0; } + /// + /// Returns the seed that was used to initialize the RNG. + /// public uint GetSeed() { return Seed; } + /// + /// Returns the entire state of the RNG as a string. + /// public string PrintState() { var s = ""; @@ -46,7 +60,11 @@ namespace MoonTools.ECS return s; } - // expects a span of STATE_BYTE_COUNT bytes + /// + /// Saves the entire state of the RNG to a Span. + /// + /// Must be a span of at least STATE_BYTE_COUNT bytes. + /// Thrown if the byte span is too short. public unsafe void SaveState(Span bytes) { #if DEBUG @@ -69,7 +87,11 @@ namespace MoonTools.ECS } } - // expects a span of STATE_BYTE_COUNT bytes + /// + /// Loads the entire state of the RNG from a Span. + /// + /// Must be a span of at least STATE_BYTE_COUNT bytes. + /// Thrown if the byte span is too short. public unsafe void LoadState(Span bytes) { #if DEBUG @@ -109,17 +131,25 @@ namespace MoonTools.ECS return State[Index]; } - // .NET Random API always returns a non-negative signed int. Fun! + /// + /// Returns a non-negative signed integer. + /// public int Next() { return (int) (NextInternal() >>> 1); // unsigned bitshift right to get rid of signed bit } - public int Next(int n) + /// + /// Returns a non-negative signed integer less than max. + /// + public int Next(int max) { - return (int) (((double) Next()) * n / int.MaxValue); + return (int) (((double) Next()) * max / int.MaxValue); } + /// + /// Returns a signed integer greater than or equal to min and less than max. + /// public int Next(int min, int max) { var diff = max - min; @@ -127,6 +157,9 @@ namespace MoonTools.ECS return min + next; } + /// + /// Returns a non-negative signed 64 bit integer. + /// public long NextInt64() { long next = NextInternal(); @@ -136,12 +169,18 @@ namespace MoonTools.ECS return next; } - public long NextInt64(long n) + /// + /// Returns a non-negative signed 64 bit integer less than max. + /// + public long NextInt64(long max) { var next = NextInt64(); - return (long) (((double) next) * n / long.MaxValue); + return (long) (((double) next) * max / long.MaxValue); } + /// + /// Returns a non-negative signed 64 bit integer greater than or equal to min and less than max. + /// public long NextInt64(long min, long max) { var diff = max - min; @@ -149,12 +188,18 @@ namespace MoonTools.ECS return min + next; } - public float NextFloat() + /// + /// Returns a single-precision floating point value between 0 and 1. + /// + public float NextSingle() { var n = NextInternal(); return ((float) n) / uint.MaxValue; } + /// + /// Returns a double-precision floating point value between 0 and 1. + /// public double NextDouble() { var n = NextInternal();