以前写程序的时候,经常用到随机函数。不过也就事随手拿了一用完成目的而已。不知道今天怎么了特别想看看随机函数的算法是怎么回事。于是结合
<a href="http://dotnet.di.unipi.it/Content/sscli/docs/doxygen/fx/bcl/random_8cs-source.html">http://dotnet.di.unipi.it/Content/sscli/docs/doxygen/fx/bcl/random_8cs-source.html</a>
归纳了一下:
using System;
class MyRnd
...{
private const int MBIG = Int32.MaxValue;
private const int MSEED = 161803398;
private const int MZ = 0;
private int inext, inextp;
private int[] SeedArray = new int[56];
public MyRnd()
: this(Environment.TickCount)
//一个 32 位带符号整数,它包含自上次启动计算机以来所经过的时间(以毫秒为单位)。
...{
}
public MyRnd(int Seed)
int ii;
int mj, mk;
//Initialize our Seed array.
//This algorithm comes from Numerical Recipes in C (2nd Ed.)
mj = MSEED - Math.Abs(Seed);
SeedArray[55] = mj;
mk = 1;
for (int i = 1; i < 55; i++)
...{ //Apparently the range [1..55] is special (Knuth) and so we're wasting the 0'th position.
ii = (21 * i) % 55;
SeedArray[ii] = mk;
mk = mj - mk;
if (mk < 0) mk += MBIG;
mj = SeedArray[ii];
}
for (int k = 1; k < 5; k++)
...{
for (int i = 1; i < 56; i++)
...{
SeedArray[i] -= SeedArray[1 + (i + 30) % 55];
if (SeedArray[i] < 0)
SeedArray[i] += MBIG;
}
inext = 0;
inextp = 21;
Seed = 1;
//产生0~1的double数
protected virtual double Sample()
int retVal;
int locINext = inext;
int locINextp = inextp;
if (++locINext >= 56) locINext = 1;
if (++locINextp >= 56) locINextp = 1;
retVal = SeedArray[locINext] - SeedArray[locINextp];
if (retVal < 0) retVal += MBIG;
SeedArray[locINext] = retVal;
inext = locINext;
inextp = locINextp;
return (retVal * (1.0 / MBIG));
public virtual double NextDouble()
return Sample();
public virtual int Next(int minValue, int maxValue) ...{
if (minValue>maxValue) ...{
throw new ArgumentOutOfRangeException("Argument_MinMaxValue");
}
int range = (maxValue-minValue);
//This is the case where we flipped around (e.g. MaxValue-MinValue);
if (range<0) ...{
long longRange = (long)maxValue-(long)minValue;
return (int)(((long)(Sample()*((double)longRange)))+minValue);
return ((int)(Sample()*(range)))+minValue;
}
}
使用方法:
static void Main(string[] args)
MyRnd r = new MyRnd();
Console.WriteLine(r.NextDouble().ToString());
Console.Read();