Add Prev for xorshift implementation

Add some unit tests (why not?)
This commit is contained in:
Kurt 2022-01-12 17:05:16 -08:00
parent bb2a63bbce
commit be8b12dbbe
2 changed files with 68 additions and 0 deletions

View file

@ -63,6 +63,26 @@ public ref struct XorShift128
return w = w ^ (w >> 19) ^ t ^ (t >> 8);
}
/// <summary>
/// Gets the previous random <see cref="ulong"/>.
/// </summary>
public uint Prev()
{
var t = w ^ z ^ (z >> 19);
t ^= t >> 8;
t ^= t >> 16;
w = z;
z = y;
y = x;
t ^= t << 11;
t ^= t << 22;
x = t;
return w;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public uint NextUInt() => (uint)NextInt();

View file

@ -0,0 +1,48 @@
using FluentAssertions;
using PKHeX.Core;
using Xunit;
namespace PKHeX.Tests;
public static class XorShiftTests
{
[Theory]
[InlineData(0x7F996375F5A791FC, 0xF3A995138EC18148, 0x50188547081C7BEC, 0x0DA245AA536BEF36, 99, 1000)]
public static void Forward(ulong s0, ulong s1, ulong n0, ulong n1, int frames, int loop)
{
var adv = GetFramesForward(s0, s1, n0, n1, loop);
adv.Should().Be(frames);
}
[Theory]
[InlineData(0x7F996375F5A791FC, 0xF3A995138EC18148, 0x50188547081C7BEC, 0x0DA245AA536BEF36, 99, 1000)]
public static void Reverse(ulong s0, ulong s1, ulong n0, ulong n1, int frames, int loop)
{
var adv = GetFramesReverse(s0, s1, n0, n1, loop);
adv.Should().Be(frames);
}
private static int GetFramesReverse(ulong s0, ulong s1, ulong n0, ulong n1, int loop)
{
var rand = new XorShift128(n0, n1);
for (int i = 0; i < loop; i++)
{
_ = rand.Prev();
if (rand.GetState64() == (s0, s1))
return i;
}
return -1;
}
private static int GetFramesForward(ulong s0, ulong s1, ulong n0, ulong n1, int loop)
{
var rand = new XorShift128(s0, s1);
for (int i = 0; i < loop; i++)
{
_ = rand.Next();
if (rand.GetState64() == (n0, n1))
return i;
}
return -1;
}
}