none
怎样产生一串int类型的随机数 RRS feed

  • 问题

  • Random rnd = new Random();

    byte[] keys = new byte[10];

    rnd.NextBytes(keys);

    以上代码用NextBytes方法产生了10个随机数,但是范围太小了,十个随机数只有0~255。

    我想要10个0~2147483647的随机数,也就是int类型的数。

    int []keys = new int[10],i;
    Random rnd = new Random();

    for(i = 0; i < 10; i++)

    keys[i] = rnd.next();

    如果用以上代码的话,keys里边的10个数都是一样的。请问我该怎么办!


    2011年10月29日 16:11

答案

全部回复

  • 产生随机数一样的原因:随机数种子没有被分到,同时因为for执行太快,来不及产生一定的时间相应随机数。方法如下:

    int []keys = new int[10],i;
    Random rnd = new Random(DateTime.Now);

    for(i = 0; i < 10; i++)
    {
    keys[i] = rnd.next();
    Thread.Sleep(100);
    }


    如果你有其它意见或私下交流,请直接发送maledong_work@foxmail.com;或者讨论(Talk)
    If you do not have QQ, please open the page and download it and click the image to talk or leave message for me.
    下载MSDN桌面工具(Vista,Win7)
    我的博客园
    慈善点击,点击此处
    2011年10月30日 3:57
    版主
  • 我现在用这段代码:

            static void Main(string[] args)
            {
                Random rnd = new Random(60);
                int []key = new int[10];
                for (int i = 0; i < 10; i++)
                {
                    key[i] = rnd.Next();
                    Console.WriteLine(key[i]);
                }
                Console.ReadKey();
            }

    执行之后打印出10个不同的数,第二次再执行还是这十个数。Random rnd = new Random(60);把60换成100以后,就成另外一批10个数了。60和100的差别我知道,是因为种子不一样,但是为什么用同一个种子会产生10个不一样的数呢?如果说当i = 0时是以60为种子产生的第一个数,那么当i = 1时又是用什么来产生第二个数呢?难道不是60吗?

    2011年10月30日 5:53
  • 不是。

    因为seed只是用于初始化产生随机数的序列种子而已。这个原理比较复杂。我不是非常说的清楚。你可以看Random原码——

    [ComVisible(true)]
    [Serializable]
    public class Random
    {
        private int inext;

        private int inextp;

        private const int MBIG = 2147483647;

        private const int MSEED = 161803398;

        private const int MZ = 0;

        private int[] SeedArray;

        public Random()
        {
        }

        public Random(int Seed)
        {
            this.SeedArray = new int[56];
            base();
            int seedArray = 161803398 - Math.Abs(Seed);
            this.SeedArray[55] = seedArray;
            int num1 = 1;
            for (int i = 1; i < 55; i++)
            {
                int num2 = 21 * i % 55;
                this.SeedArray[num2] = num1;
                num1 = seedArray - num1;
                if (num1 < 0)
                {
                    num1 = num1 + 2147483647;
                }
                seedArray = this.SeedArray[num2];
            }
            for (int j = 1; j < 5; j++)
            {
                for (int k = 1; k < 56; k++)
                {
                    this.SeedArray[k] = this.SeedArray[k] - this.SeedArray[1 + (k + 30) % 55];
                    if (this.SeedArray[k] < 0)
                    {
                        this.SeedArray[k] = this.SeedArray[k] + 2147483647;
                    }
                }
            }
            this.inext = 0;
            this.inextp = 21;
            Seed = 1;
        }

        private double GetSampleForLargeRange()
        {
            int num1 = this.InternalSample();
            if (!(this.InternalSample() % 2) || 0)
            {
                num1 = -num1;
            }
            double num2 = (double)num1;
            num2 = num2 + 2147483646.00;
            num2 = num2 / 4294967293.00;
            return num2;
        }

        private int InternalSample()
        {
            int num1 = this.inext;
            int num2 = this.inextp;
            if (++num1 >= 56)
            {
                num1 = 1;
            }
            if (++num2 >= 56)
            {
                num2 = 1;
            }
            int seedArray = this.SeedArray[num1] - this.SeedArray[num2];
            if (seedArray < 0)
            {
                seedArray = seedArray + 2147483647;
            }
            this.SeedArray[num1] = seedArray;
            this.inext = num1;
            this.inextp = num2;
            return seedArray;
        }

        public virtual int Next()
        {
            return this.InternalSample();
        }

        public virtual int Next(int minValue, int maxValue)
        {
            object[] objArray;
            if (minValue > maxValue)
            {
                throw new ArgumentOutOfRangeException("minValue", string.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Argument_MinMaxValue"), new object[] { "minValue", "maxValue" }));
            }
            long num = (long)maxValue - (long)minValue;
            if (num <= (long)2147483647)
            {
                return (int)this.Sample() * (double)num + minValue;
            }
            return (int)(long)this.GetSampleForLargeRange() * (double)num + (long)minValue;
        }

        public virtual int Next(int maxValue)
        {
            object[] objArray;
            if (maxValue < 0)
            {
                throw new ArgumentOutOfRangeException("maxValue", string.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("ArgumentOutOfRange_MustBePositive"), new object[] { "maxValue" }));
            }
            return (int)this.Sample() * (double)maxValue;
        }

        public virtual void NextBytes(byte[] buffer)
        {
            if (buffer == 0)
            {
                throw new ArgumentNullException("buffer");
            }
            for (int i = 0; i < (int)buffer.Length; i++)
            {
                buffer[i] = (byte)this.InternalSample() % 256;
            }
        }

        public virtual double NextDouble()
        {
            return this.Sample();
        }

        protected virtual double Sample()
        {
            return (double)this.InternalSample() * 0.00;
        }
    }

     


    如果你有其它意见或私下交流,请直接发送maledong_work@foxmail.com;或者讨论(Talk)
    If you do not have QQ, please open the page and download it and click the image to talk or leave message for me.
    下载MSDN桌面工具(Vista,Win7)
    我的博客园
    慈善点击,点击此处
    2011年10月30日 6:17
    版主
  • 我现在用这段代码:

            static void Main(string[] args)
            {
                Random rnd = new Random(60);
                int []key = new int[10];
                for (int i = 0; i < 10; i++)
                {
                    key[i] = rnd.Next();
                    Console.WriteLine(key[i]);
                }
                Console.ReadKey();
            }

    执行之后打印出10个不同的数,第二次再执行还是这十个数。Random rnd = new Random(60);把60换成100以后,就成另外一批10个数了。60和100的差别我知道,是因为种子不一样,但是为什么用同一个种子会产生10个不一样的数呢?如果说当i = 0时是以60为种子产生的第一个数,那么当i = 1时又是用什么来产生第二个数呢?难道不是60吗?


    請愛用Guid.NewGuid().GetHashCode()

    Random rnd = new Random(Guid.NewGuid().GetHashCode());

    產生的亂數比較不會重覆


    Shadowと愉快なコード達
    2011年10月30日 15:05