mirror of
https://github.com/Thealexbarney/LibHac.git
synced 2024-11-14 10:49:41 +01:00
66 lines
1.8 KiB
C#
66 lines
1.8 KiB
C#
|
using System;
|
|||
|
using System.Numerics;
|
|||
|
using System.Runtime.InteropServices;
|
|||
|
|
|||
|
namespace LibHac.Tests
|
|||
|
{
|
|||
|
public struct Random
|
|||
|
{
|
|||
|
private ulong _state1;
|
|||
|
private ulong _state2;
|
|||
|
|
|||
|
public Random(ulong seed)
|
|||
|
{
|
|||
|
ulong x = seed;
|
|||
|
ulong z = x + 0x9e3779b97f4a7c15;
|
|||
|
z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
|
|||
|
z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
|
|||
|
x = z ^ (z >> 31);
|
|||
|
z = (x += 0x9e3779b97f4a7c15);
|
|||
|
z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
|
|||
|
z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
|
|||
|
_state1 = z ^ (z >> 31);
|
|||
|
_state2 = x;
|
|||
|
}
|
|||
|
|
|||
|
ulong Next()
|
|||
|
{
|
|||
|
ulong s0 = _state1;
|
|||
|
ulong s1 = _state2;
|
|||
|
ulong result = BitOperations.RotateLeft(s0 + s1, 17) + s0;
|
|||
|
|
|||
|
s1 ^= s0;
|
|||
|
_state1 = BitOperations.RotateLeft(s0, 49) ^ s1 ^ (s1 << 21);
|
|||
|
_state2 = BitOperations.RotateLeft(s1, 28);
|
|||
|
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
public int Next(int minValue, int maxValue)
|
|||
|
{
|
|||
|
if (minValue > maxValue)
|
|||
|
{
|
|||
|
throw new ArgumentOutOfRangeException(nameof(minValue));
|
|||
|
}
|
|||
|
|
|||
|
long range = (long)maxValue - minValue;
|
|||
|
return (int)((uint)Next() * (1.0 / uint.MaxValue) * range) + minValue;
|
|||
|
}
|
|||
|
|
|||
|
public void NextBytes(Span<byte> buffer)
|
|||
|
{
|
|||
|
Span<ulong> bufferUlong = MemoryMarshal.Cast<byte, ulong>(buffer);
|
|||
|
|
|||
|
for (int i = 0; i < bufferUlong.Length; i++)
|
|||
|
{
|
|||
|
bufferUlong[i] = Next();
|
|||
|
}
|
|||
|
|
|||
|
for (int i = bufferUlong.Length * sizeof(ulong); i < buffer.Length; i++)
|
|||
|
{
|
|||
|
buffer[i] = (byte)Next();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|