Last active
October 19, 2015 11:18
-
-
Save mohemohe/8992e22745a50a9f2c3c to your computer and use it in GitHub Desktop.
Xorshift128
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <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