using System; using System.Collections.Generic; using System.Text; namespace Uber.Core { public class Quick : RandomBase { #region Constructors public Quick() : this(Convert.ToInt32(DateTime.Now.Ticks & 0x000000007FFFFFFF)) { } public Quick(int seed) : base(seed) { i = Convert.ToUInt64(GetBaseNextInt32()); } #endregion #region Member Variables private static readonly uint a = 1099087573; private ulong i; #endregion #region Methods public override int Next() { #region Execution i = a * i; // overflow occurs here! return ConvertToInt32(i); #endregion } #endregion } public abstract class RandomBase : Random { #region Constructors public RandomBase() { } public RandomBase(int seed) : base(seed) { } #endregion #region Methods protected int GetBaseNextInt32() { return base.Next(); } protected uint GetBaseNextUInt32() { return ConvertToUInt32(base.Next()); } protected double GetBaseNextDouble() { return base.NextDouble(); } #endregion #region Overrides public abstract override int Next(); public override int Next(int maxValue) { return Next(0, maxValue); } public override int Next(int minValue, int maxValue) { return Convert.ToInt32((maxValue - minValue) * Sample() + minValue); } public override double NextDouble() { return Sample(); } public override void NextBytes(byte[] buffer) { int i, j, tmp; // fill the part of the buffer that can be covered by full Int32s for (i = 0; i < buffer.Length - 4; i += 4) { tmp = Next(); buffer[i] = Convert.ToByte(tmp & 0x000000FF); buffer[i + 1] = Convert.ToByte((tmp & 0x0000FF00) >> 8); buffer[i + 2] = Convert.ToByte((tmp & 0x00FF0000) >> 16); buffer[i + 3] = Convert.ToByte((tmp & 0xFF000000) >> 24); } tmp = Next(); // fill the rest of the buffer for (j = 0; j < buffer.Length % 4; j++) { buffer[i + j] = Convert.ToByte(((tmp & (0x000000FF << (8 * j))) >> (8 * j))); } } protected override double Sample() { // generates a random number on [0,1) return Convert.ToDouble(Next()) / 2147483648.0; // divided by 2^31 (Int32 absolute value) } #endregion #region Utility Methods protected static UInt32 ConvertToUInt32(Int32 value) { return BitConverter.ToUInt32(BitConverter.GetBytes(value), 0); } protected static Int32 ConvertToInt32(UInt32 value) { return BitConverter.ToInt32(BitConverter.GetBytes(value), 0); } protected static Int32 ConvertToInt32(UInt64 value) { return BitConverter.ToInt32(BitConverter.GetBytes(value & 0x000000007fffffff), 0); } #endregion } }