Skip to content

Instantly share code, notes, and snippets.

@kyuskoj
Last active September 25, 2021 13:31
Show Gist options
  • Save kyuskoj/9319f90c70130844eac7b737f955e799 to your computer and use it in GitHub Desktop.
Save kyuskoj/9319f90c70130844eac7b737f955e799 to your computer and use it in GitHub Desktop.
simple Xoroshiro128Plus for Unity.
using System;
namespace Pulsar.Utils
{
public static class Xoroshiro128Plus
{
private const int A = 24, B = 16, C = 37;
// float has a maximum of '24' bits of precision. This means that not all integers larger than 16777216 can be represented exactly.
private const long FloatMask = (1L << 24) - 1;
private const float Normalize24 = 1.0f / (1L << 24);
private static ulong state0, state1;
public static void InitState(int seed) => InitState((ulong)seed);
public static void InitState(ulong seed)
{
state0 = SplitMix64(ref seed);
state1 = SplitMix64(ref seed);
if ((state0 | state1) == 0) state0 = 1;
}
// min inclusive, max exclusive
public static int Range(int minValue, int maxValue) => minValue + (int)Math.Floor(Fracture(maxValue - minValue));
// min inclusive, max exclusive
public static float Range(float minValue, float maxValue) => minValue + Fracture(maxValue - minValue);
private static float NextFloat() => ((long)Next() & FloatMask) * Normalize24;
private static float Fracture(float f) => NextFloat() * f;
private static ulong Next()
{
ulong s0 = state0;
ulong s1 = state1;
ulong res = s0 + s1;
s1 ^= s0;
state0 = Rotate(s0, A) ^ s1 ^ (s1 << B);
state1 = Rotate(s1, C);
return res;
}
private static ulong SplitMix64(ref ulong x)
{
ulong z = (x += 0x9E3779B97F4A7C15UL);
z = (z ^ (z >> 30)) * 0xBF58476D1CE4E5B9UL;
z = (z ^ (z >> 27)) * 0x94D049BB133111EBUL;
return z ^ (z >> 31);
}
private static ulong Rotate(ulong x, int k) => (x << k) | (x >> (64 - k));
}
}
@kyuskoj
Copy link
Author

kyuskoj commented Apr 28, 2021

Standard deviation tested.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment