From 8ffd9ab48a643f1dde82a8b8e19145593ed4ece1 Mon Sep 17 00:00:00 2001 From: Ellpeck Date: Wed, 30 Nov 2022 00:24:43 +0100 Subject: [PATCH] improved and cleaned up SingleRandom --- MLEM/Misc/SingleRandom.cs | 20 ++++++++++++-------- Tests/SingleRandomTests.cs | 13 ++++++------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/MLEM/Misc/SingleRandom.cs b/MLEM/Misc/SingleRandom.cs index 8e5bcdf..4b35100 100644 --- a/MLEM/Misc/SingleRandom.cs +++ b/MLEM/Misc/SingleRandom.cs @@ -24,7 +24,7 @@ namespace MLEM.Misc { /// /// The seeds to use. /// The generated number. - public static int Int(int[] seeds) { + public static int Int(params int[] seeds) { return (int) (SingleRandom.Single(seeds) * int.MaxValue); } @@ -46,7 +46,7 @@ namespace MLEM.Misc { /// The (exclusive) maximum value. /// The seeds to use. /// The generated number. - public static int Int(int maxValue, int[] seeds) { + public static int Int(int maxValue, params int[] seeds) { return (int) (maxValue * SingleRandom.Single(seeds)); } @@ -70,7 +70,7 @@ namespace MLEM.Misc { /// The (exclusive) maximum value. /// The seeds to use. /// The generated number. - public static int Int(int minValue, int maxValue, int[] seeds) { + public static int Int(int minValue, int maxValue, params int[] seeds) { return (int) ((maxValue - minValue) * SingleRandom.Single(seeds)) + minValue; } @@ -90,7 +90,7 @@ namespace MLEM.Misc { /// /// The seeds to use. /// The generated number. - public static float Single(int[] seeds) { + public static float Single(params int[] seeds) { return (SingleRandom.Scramble(seeds) / (float) int.MaxValue + 1) / 2; } @@ -112,7 +112,7 @@ namespace MLEM.Misc { /// The (exclusive) maximum value. /// The seeds to use. /// The generated number. - public static float Single(float maxValue, int[] seeds) { + public static float Single(float maxValue, params int[] seeds) { return maxValue * SingleRandom.Single(seeds); } @@ -136,20 +136,24 @@ namespace MLEM.Misc { /// The (exclusive) maximum value. /// The seeds to use. /// The generated number. - public static float Single(float minValue, float maxValue, int[] seeds) { + public static float Single(float minValue, float maxValue, params int[] seeds) { return (maxValue - minValue) * SingleRandom.Single(seeds) + minValue; } private static int Scramble(int[] seeds) { if (seeds == null || seeds.Length <= 0) throw new ArgumentOutOfRangeException(nameof(seeds)); - var ret = 1; + var ret = 1623487; for (var i = 0; i < seeds.Length; i++) - ret *= SingleRandom.Scramble(seeds[i]); + ret += SingleRandom.ScrambleStep(seeds[i]) * 68659; return ret; } private static int Scramble(int seed) { + return SingleRandom.ScrambleStep(seed) * 68659 + 1623487; + } + + private static int ScrambleStep(int seed) { seed ^= (seed << 7); seed *= 207398809; seed ^= (seed << 17); diff --git a/Tests/SingleRandomTests.cs b/Tests/SingleRandomTests.cs index 5795886..ae28aa3 100644 --- a/Tests/SingleRandomTests.cs +++ b/Tests/SingleRandomTests.cs @@ -16,8 +16,8 @@ public class SingleRandomTests { // test if all methods that accept mins and max are identical Assert.AreEqual(SingleRandom.Int(i), SingleRandom.Int(int.MaxValue, i)); Assert.AreEqual(SingleRandom.Int(i), SingleRandom.Int(0, int.MaxValue, i)); - Assert.AreEqual(SingleRandom.Single(i), SingleRandom.Single(1, i)); - Assert.AreEqual(SingleRandom.Single(i), SingleRandom.Single(0, 1, i)); + Assert.AreEqual(SingleRandom.Single(i), SingleRandom.Single(1F, i)); + Assert.AreEqual(SingleRandom.Single(i), SingleRandom.Single(0F, 1F, i)); } } @@ -25,8 +25,8 @@ public class SingleRandomTests { public void TestBounds() { for (var i = 0; i < 1000000; i++) { Assert.That(SingleRandom.Single(i), Is.LessThan(1).And.GreaterThanOrEqualTo(0)); - Assert.That(SingleRandom.Single(127, i), Is.LessThan(127).And.GreaterThanOrEqualTo(0)); - Assert.That(SingleRandom.Single(12920, 1203919023, i), Is.LessThan(1203919023).And.GreaterThanOrEqualTo(12920)); + Assert.That(SingleRandom.Single(127F, i), Is.LessThan(127).And.GreaterThanOrEqualTo(0)); + Assert.That(SingleRandom.Single(12920F, 1203919023F, i), Is.LessThan(1203919023).And.GreaterThanOrEqualTo(12920)); Assert.That(SingleRandom.Int(i), Is.LessThan(int.MaxValue).And.GreaterThanOrEqualTo(0)); Assert.That(SingleRandom.Int(17, i), Is.LessThan(17).And.GreaterThanOrEqualTo(0)); @@ -42,9 +42,8 @@ public class SingleRandomTests { ints.Add(SingleRandom.Int(i)); flts.Add(SingleRandom.Single(i)); } - // allow being off by 0.00001 of the total - Assert.AreEqual(ints.Average(), int.MaxValue / 2, 0.00001 * int.MaxValue); - Assert.AreEqual(flts.Average(), 0.5, 0.00001); + Assert.AreEqual(0.5, ints.Average() / int.MaxValue, 0.001); + Assert.AreEqual(0.5, flts.Average(), 0.001); } }