代码如下 for (int i = 0; i <3; i++)
{
int[] r = new int[1];
Random rd=new Random();
r[0] = rd.Next(0,9);
foreach (var item in r)
{
this.textBox1.Text = this.textBox1.Text + item;
} r = null;
}
输出结果: 为三个相同的数。我就纳闷了每次都清空了重新赋值了为什么还是得到相同的结果呢?如果把 rd.Next(0,9) 改为i 就会得到 0 1 2 说明正确的呀
{
int[] r = new int[1];
Random rd=new Random();
r[0] = rd.Next(0,9);
foreach (var item in r)
{
this.textBox1.Text = this.textBox1.Text + item;
} r = null;
}
输出结果: 为三个相同的数。我就纳闷了每次都清空了重新赋值了为什么还是得到相同的结果呢?如果把 rd.Next(0,9) 改为i 就会得到 0 1 2 说明正确的呀
http://msdn.microsoft.com/zh-cn/library/system.random.aspx
也就是当你new一个 random
然后 获取第一次随机数。
和你另外new一个 random
获取第一次随机数
得到的值,都是相等的。
namespace ConsoleApplication2
{
public class Random1
{
private int inext;
private int inextp;
private const int MBIG = 0x7fffffff;
private const int MSEED = 0x9a4ec86;
private const int MZ = 0;
private int[] SeedArray; public Random1()
: this(Environment.TickCount)
{
} public Random1(int Seed)
{
this.SeedArray = new int[0x38];
int num2 = 0x9a4ec86 - Math.Abs(Seed);
this.SeedArray[0x37] = num2;
int num3 = 1;
for (int i = 1; i < 0x37; i++)
{
int index = (0x15 * i) % 0x37;
this.SeedArray[index] = num3;
num3 = num2 - num3;
if (num3 < 0)
{
num3 += 0x7fffffff;
}
num2 = this.SeedArray[index];
}
for (int j = 1; j < 5; j++)
{
for (int k = 1; k < 0x38; k++)
{
this.SeedArray[k] -= this.SeedArray[1 + ((k + 30) % 0x37)];
if (this.SeedArray[k] < 0)
{
this.SeedArray[k] += 0x7fffffff;
}
}
}
this.inext = 0;
this.inextp = 0x15;
Seed = 1;
} private double GetSampleForLargeRange()
{
int num = this.InternalSample();
if ((this.InternalSample() % 2) == 0)
{
num = -num;
}
double num2 = num;
num2 += 2147483646.0;
return (num2 / 4294967293);
} private int InternalSample()
{
int inext = this.inext;
int inextp = this.inextp;
Console.WriteLine("inext:{0} inextp:{1}", inext, inextp);
if (++inext >= 0x38)
{
inext = 1;
}
if (++inextp >= 0x38)
{
inextp = 1;
}
int num = this.SeedArray[inext] - this.SeedArray[inextp];
if (num < 0)
{
num += 0x7fffffff;
}
this.SeedArray[inext] = num;
this.inext = inext;
this.inextp = inextp;
return num;
} public virtual int Next()
{
return this.InternalSample();
} public virtual int Next(int maxValue)
{
if (maxValue < 0)
{
throw new ArgumentOutOfRangeException("maxValue");
}
return (int)(this.Sample() * maxValue);
} public virtual int Next(int minValue, int maxValue)
{
if (minValue > maxValue)
{
throw new ArgumentOutOfRangeException("minValue");
}
long num = maxValue - minValue;
if (num <= 0x7fffffff)
{
return (((int)(this.Sample() * num)) + minValue);
}
return (((int)((long)(this.GetSampleForLargeRange() * num))) + minValue);
} public virtual void NextBytes(byte[] buffer)
{
if (buffer == null)
{
throw new ArgumentNullException("buffer");
}
for (int i = 0; i < buffer.Length; i++)
{
buffer[i] = (byte)(this.InternalSample() % 0x100);
}
} public virtual double NextDouble()
{
return this.Sample();
} protected virtual double Sample()
{
return (this.InternalSample() * 4.6566128752457969E-10);
}
}
class Program
{
static void Main(string[] args)
{
Random1 rd = new Random1();
for (int i = 0; i < 3; i++)
{
int r = rd.Next(0, 9);
Console.WriteLine(r);
}
Console.Read();
}
}
}
Random1类就是Random的源代码,可以看见他初始化的时候,如果调用默认构造函数,将调用Environment.TickCount作为他的种子,而这个值在这个环境里,是不变的初始化操作将初始化 inext, inextp这两个变量Random1 rd = new Random1();放在for外面的时候,每次调用Next函数,都要使用 inext, inextp这两个变量,使用完后,将重新赋值 inext, inextp,得到新的值,所以下次调用Next的时候,将得到不同的随机数而Random1 rd = new Random1();放在for里面的话,Next永远是对当前实例化对象的第一次调用因为每个Randowm对象实例的Environment.TickCount相同 推导出 初始化的inext, inextp相同 推导出 第一次调用Next函数得到的随机数相同
默认种子值是从系统时钟派生而来的,具有有限的分辨率。因此,通过调用默认构造函数而频繁创建的不同 Random 对象将具有相同的默认种子值
摘自:
http://msdn.microsoft.com/zh-cn/library/h343ddh9.aspx
承认错误!
随机数生成与系统时间有关。并非我所解释的样子,CSDN不能修改回帖。。
很抱歉!
7L后面几句要表达的意思,就是就是频繁创建多个Random对象实例后将具有相同的默认种子值(即获得相同的随机数)
而重复的种子就会导致重复的随机数,
7楼的兄弟已经更正了
这个就不明白了,Environment.TickCount包含自上次启动计算机以来所经过的毫秒数,那这个时间对于当前环境应该是个定值那么多个实例化话,引用的种子应该都是相同的嘛Environment.TickCount应该是在系统重启后变化吧PS:大哥你怎么一会有星,一会没星