Skip to content

Instantly share code, notes, and snippets.

@mohemohe
Last active October 19, 2015 11:18
Show Gist options
  • Save mohemohe/8992e22745a50a9f2c3c to your computer and use it in GitHub Desktop.
Save mohemohe/8992e22745a50a9f2c3c to your computer and use it in GitHub Desktop.
Xorshift128
/// <summary>
/// System.Random と同じような感じで使える Xorshift
/// </summary>
class Xorshift
{
ulong x = 123456789, y = 362436069, z = 521288629, w;
/// <summary>
/// マジックナンバーによる固定のシード値を使用して、 Xorshift インスタンスを初期化します
/// </summary>
/// <param name="seed">指定したシード値を使用して、 Xorshift インスタンスを初期化します</param>
public Xorshift(ulong seed = 88675123)
{
w = seed;
// 適度に読み飛ばす
for (var i = 0; i < 32; i++) xor128();
}
/// <summary>
/// 0 以上の乱数を返します
/// </summary>
/// <returns></returns>
public ulong NextUlong()
{
return xor128();
}
/// <summary>
/// 指定した最大値より小さい 0 以上の乱数を返します
/// </summary>
/// <param name="max">最大値</param>
/// <returns></returns>
public ulong NextUlong(ulong max)
{
var raw = xor128();
if (max == 0) return 0;
return raw % max;
}
/// <summary>
/// 指定した範囲内の乱数を返します
/// </summary>
/// <param name="min">最小値</param>
/// <param name="max">最大値</param>
/// <returns></returns>
public ulong NextUlong(ulong min, ulong max)
{
var raw = xor128();
if (max - min == 0) return min;
return raw % (max - min);
}
/// <summary>
/// 0 以上の乱数を返します
/// </summary>
/// <returns></returns>
public int Next()
{
var raw = xor128();
return (int)(raw % int.MaxValue);
}
/// <summary>
/// 指定した最大値より小さい 0 以上の乱数を返します
/// </summary>
/// <param name="max">最大値</param>
/// <returns></returns>
public int Next(int max)
{
if (max == 0) return 0;
var raw = xor128();
return (int)(raw % (uint)max);
}
/// <summary>
/// 指定した範囲内の乱数を返します
/// </summary>
/// <param name="min">最小値</param>
/// <param name="max">最大値</param>
/// <returns></returns>
public int Next(int min, int max)
{
if (max == 0) return 0;
var raw = xor128();
return (int)(raw % (uint)(max - min));
}
/// <summary>
/// 0.0 と 1.0 の間の乱数を返します
/// </summary>
/// <returns></returns>
public double NextDouble()
{
var raw = xor128();
return (double)raw / ulong.MaxValue;
}
private ulong xor128()
{
ulong t = x ^ (x << 11);
x = y; y = z; z = w;
return w = (w ^ (w >> 19)) ^ (t ^ (t >> 8));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment