Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public class MersenneTwister : Random
- {
- private const int N = 624;
- private const int M = 397;
- private const uint MatrixA = 0x9908b0df;
- private const uint UpperMask = 0x80000000;
- private const uint LowerMask = 0x7fffffff;
- private const uint TemperingMaskB = 0x9d2c5680;
- private const uint TemperingMaskC = 0xefc60000;
- private static uint TEMPERING_SHIFT_U(uint y)
- {
- return (y >> 11);
- }
- private static uint TEMPERING_SHIFT_S(uint y)
- {
- return (y << 7);
- }
- private static uint TEMPERING_SHIFT_T(uint y)
- {
- return (y << 15);
- }
- private static uint TEMPERING_SHIFT_L(uint y)
- {
- return (y >> 18);
- }
- private readonly uint[] _mt = new uint[N];
- private short _mti;
- private static readonly uint[] _mag01 = { 0x0, MatrixA };
- public MersenneTwister(uint seed)
- {
- _mt[0] = seed & 0xffffffffU;
- for (_mti = 1; _mti < N; ++_mti)
- {
- _mt[_mti] = (69069 * _mt[_mti - 1]) & 0xffffffffU;
- }
- }
- public MersenneTwister()
- : this(4357)
- {
- }
- protected uint GenerateUInt()
- {
- uint y;
- if (_mti >= N)
- {
- short kk = 0;
- for (; kk < N - M; ++kk)
- {
- y = (_mt[kk] & UpperMask) | (_mt[kk + 1] & LowerMask);
- _mt[kk] = _mt[kk + M] ^ (y >> 1) ^ _mag01[y & 0x1];
- }
- for (; kk < N - 1; ++kk)
- {
- y = (_mt[kk] & UpperMask) | (_mt[kk + 1] & LowerMask);
- _mt[kk] = _mt[kk + (M - N)] ^ (y >> 1) ^ _mag01[y & 0x1];
- }
- y = (_mt[N - 1] & UpperMask) | (_mt[0] & LowerMask);
- _mt[N - 1] = _mt[M - 1] ^ (y >> 1) ^ _mag01[y & 0x1];
- _mti = 0;
- }
- y = _mt[_mti++];
- y ^= TEMPERING_SHIFT_U(y);
- y ^= TEMPERING_SHIFT_S(y) & TemperingMaskB;
- y ^= TEMPERING_SHIFT_T(y) & TemperingMaskC;
- y ^= TEMPERING_SHIFT_L(y);
- return y;
- }
- public virtual uint NextUInt()
- {
- return this.GenerateUInt();
- }
- public virtual uint NextUInt(uint maxValue)
- {
- return (uint)(this.GenerateUInt() / ((double)uint.MaxValue / maxValue));
- }
- public virtual uint NextUInt(uint minValue, uint maxValue)
- {
- if (minValue >= maxValue)
- {
- throw new ArgumentOutOfRangeException();
- }
- return (uint)(this.GenerateUInt() / ((double)uint.MaxValue / (maxValue - minValue)) + minValue);
- }
- public override int Next()
- {
- return this.Next(int.MaxValue);
- }
- public override int Next(int maxValue)
- {
- if (maxValue <= 1)
- {
- if (maxValue < 0)
- {
- throw new ArgumentOutOfRangeException();
- }
- return 0;
- }
- return (int)(this.NextDouble() * maxValue);
- }
- public override int Next(int minValue, int maxValue)
- {
- if (maxValue < minValue)
- {
- throw new ArgumentOutOfRangeException();
- }
- else if (maxValue == minValue)
- {
- return minValue;
- }
- else
- {
- return this.Next(maxValue - minValue) + minValue;
- }
- }
- public override void NextBytes(byte[] buffer)
- {
- int bufLen = buffer.Length;
- if (buffer == null)
- {
- throw new ArgumentNullException();
- }
- for (int idx = 0; idx < bufLen; ++idx)
- {
- buffer[idx] = (byte)this.Next(256);
- }
- }
- public override double NextDouble()
- {
- return (double)this.GenerateUInt() / ((ulong)uint.MaxValue + 1);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement