Add prev function for xoroshiro implementations

This commit is contained in:
Kurt 2022-01-13 18:43:04 -08:00
parent 5dfd7996f7
commit 94080eb71a
4 changed files with 134 additions and 0 deletions

View file

@ -51,6 +51,25 @@ namespace PKHeX.Core
return result;
}
/// <summary>
/// Gets the next previous <see cref="ulong"/>.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ulong Prev()
{
var _s0 = s0;
var _s1 = s1;
_s1 = RotateLeft(_s1, 27);
_s0 = _s0 ^ _s1 ^ (_s1 << 16);
_s0 = RotateLeft(_s0, 40);
_s1 ^= _s0;
ulong result = _s0 + _s1;
s0 = _s0;
s1 = _s1;
return result;
}
/// <summary>
/// Gets a random value that is less than <see cref="MOD"/>
/// </summary>

View file

@ -59,6 +59,25 @@ namespace PKHeX.Core
return result;
}
/// <summary>
/// Gets the next previous <see cref="ulong"/>.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ulong Prev()
{
var _s0 = s0;
var _s1 = s1;
_s1 = RotateLeft(_s1, 27);
_s0 = _s0 ^ _s1 ^ (_s1 << 16);
_s0 = RotateLeft(_s0, 40);
_s1 ^= _s0;
ulong result = _s0 + _s1;
s0 = _s0;
s1 = _s1;
return result;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool NextBool() => (Next() >> 63) != 0;

View file

@ -0,0 +1,48 @@
using FluentAssertions;
using PKHeX.Core;
using Xunit;
namespace PKHeX.Tests;
public static class Xoroshiro128Tests
{
[Theory]
[InlineData(1, 1, 0x339C61939607D435, 0xF4DD6E2E9698D1B0, 98, 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(1, 1, 0x339C61939607D435, 0xF4DD6E2E9698D1B0, 98, 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 Xoroshiro128Plus(n0, n1);
for (int i = 0; i < loop; i++)
{
_ = rand.Prev();
if (rand.GetState() == (s0, s1))
return i;
}
return -1;
}
private static int GetFramesForward(ulong s0, ulong s1, ulong n0, ulong n1, int loop)
{
var rand = new Xoroshiro128Plus(s0, s1);
for (int i = 0; i < loop; i++)
{
_ = rand.Next();
if (rand.GetState() == (n0, n1))
return i;
}
return -1;
}
}

View file

@ -0,0 +1,48 @@
using FluentAssertions;
using PKHeX.Core;
using Xunit;
namespace PKHeX.Tests;
public static class Xoroshiro128bTests
{
[Theory]
[InlineData(1, 1, 0x339C61939607D435, 0xF4DD6E2E9698D1B0, 98, 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(1, 1, 0x339C61939607D435, 0xF4DD6E2E9698D1B0, 98, 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 Xoroshiro128Plus8b(n0, n1);
for (int i = 0; i < loop; i++)
{
_ = rand.Prev();
if (rand.GetState() == (s0, s1))
return i;
}
return -1;
}
private static int GetFramesForward(ulong s0, ulong s1, ulong n0, ulong n1, int loop)
{
var rand = new Xoroshiro128Plus8b(s0, s1);
for (int i = 0; i < loop; i++)
{
_ = rand.Next();
if (rand.GetState() == (n0, n1))
return i;
}
return -1;
}
}