public void JumpTest(long s0, long s1, long[] signedExpected)
        {
            unchecked
            {
                var                  sut       = new XoroShiro128PlusGenerator();
                RngState128          prngState = new RngState128((ulong)s0, (ulong)s1);
                ReadOnlySpan <ulong> expected  = MemoryMarshal.Cast <long, ulong>(signedExpected);

                Span <ulong> actual = stackalloc ulong[expected.Length];
                for (int i = 0; i < actual.Length; i++)
                {
                    prngState = XoroShiro128PlusGenerator.Jump(prngState);
                    prngState = sut.FillBuffer(prngState, MemoryMarshal.AsBytes(actual.Slice(i, 1)));
                }

                Assert.True(expected.SequenceEqual(actual));
            }
        }
        public void Test(ulong s0, ulong s1, ulong expectedResult1, ulong expectedResult2, ulong expectedResult3)
        {
            // this was params ulong[], but I like InlineData too much to make that work...
            Span <ulong> expectedResults = stackalloc[] { expectedResult1, expectedResult2, expectedResult3 };

            var gen           = new XorShift128PlusGenerator();
            var state         = new RngState128(s0, s1);
            var buf           = new byte[expectedResults.Length * 8].AsSpan();
            var actualResults = MemoryMarshal.Cast <byte, ulong>(buf);

            // First, do it in separate calls.
            for (int i = 0; i < expectedResults.Length; ++i)
            {
                state = gen.FillBuffer(state, buf.Slice(i * 8, 8));
                Assert.Equal(expectedResults[i], actualResults[i]);
            }

            // Now, do it all in one call.
            state = new RngState128(s0, s1);
            buf.Clear();
            gen.FillBuffer(state, buf);
            Assert.True(expectedResults.SequenceEqual(actualResults));
        }