Net中随机函数的算法

来源:互联网 发布:灵创软件 编辑:程序博客网 时间:2024/05/17 01:41

以前写程序的时候,经常用到随机函数。不过也就事随手拿了一用完成目的而已。不知道今天怎么了特别想看看随机函数的算法是怎么回事。于是结合

http://dotnet.di.unipi.it/Content/sscli/docs/doxygen/fx/bcl/random_8cs-source.html

归纳了一下:

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();
        }