找了一段东西,不是C#的,不过可以参考下:
之所以rand()每次的随机数都一样是因为rand()函数使用不正确。各种编程语言返回的随机数(确切地说是伪随机数)实际上都是根据递推公式计算的一组数值,当序列足够长,这组数值近似满足均匀分布。如果计算伪随机序列的初始数值(称为种子)相同,则计算出来的伪随机序列就是完全相同的。这个特性被有的软件利用于加密和解密。加密时,可以用某个种子数生成一个伪随机序列并对数据进行处理;解密时,再利用种子数生成一个伪随机序列并对加密数据进行还原。这样,对于不知道种子数的人要想解密就需要多费些事了。当然,这种完全相同的序列对于你来说是非常糟糕的。要解决这个问题,需要在每次产生随机序列前,先指定不同的种子,这样计算出来的随机序列就不会完全相同了。你可以在调用rand()函数之前调用srand( (unsigned)time( NULL ) ),这样以time函数值(即当前时间)作为种子数,因为两次调用rand函数的时间通常是不同的,这样就可以保证随机性了。你也可以使用srand函数来人为指定种子数。Windows 9x/NT的游戏FreeCell就允许用户指定种子数,这样用户如果一次游戏没有成功,下次还可以以同样的发牌结果再玩一次。 反复调用该方法时会产生很多相同的随机数 是因为种子数相同(每次都生成一个新的实例,不过看帮助好像是说跟时间有关的,怎么还会不变呢)
为什么用第二种方法产生的随机数不同 这个……当然是因为种子数变化了(好像是跟上一次生成的数字有关吧)
请问这个值是怎么计算出来的,有公式吗 伪随机数,公式应该是有的吧,不过知道具体公式有意义吗?
之所以rand()每次的随机数都一样是因为rand()函数使用不正确。各种编程语言返回的随机数(确切地说是伪随机数)实际上都是根据递推公式计算的一组数值,当序列足够长,这组数值近似满足均匀分布。如果计算伪随机序列的初始数值(称为种子)相同,则计算出来的伪随机序列就是完全相同的。这个特性被有的软件利用于加密和解密。加密时,可以用某个种子数生成一个伪随机序列并对数据进行处理;解密时,再利用种子数生成一个伪随机序列并对加密数据进行还原。这样,对于不知道种子数的人要想解密就需要多费些事了。当然,这种完全相同的序列对于你来说是非常糟糕的。要解决这个问题,需要在每次产生随机序列前,先指定不同的种子,这样计算出来的随机序列就不会完全相同了。你可以在调用rand()函数之前调用srand( (unsigned)time( NULL ) ),这样以time函数值(即当前时间)作为种子数,因为两次调用rand函数的时间通常是不同的,这样就可以保证随机性了。你也可以使用srand函数来人为指定种子数。Windows 9x/NT的游戏FreeCell就允许用户指定种子数,这样用户如果一次游戏没有成功,下次还可以以同样的发牌结果再玩一次。 反复调用该方法时会产生很多相同的随机数 是因为种子数相同(每次都生成一个新的实例,不过看帮助好像是说跟时间有关的,怎么还会不变呢)
为什么用第二种方法产生的随机数不同 这个……当然是因为种子数变化了(好像是跟上一次生成的数字有关吧)
请问这个值是怎么计算出来的,有公式吗 伪随机数,公式应该是有的吧,不过知道具体公式有意义吗?
new Random(n).NextDouble()对于确定的n,有确定的值,如:new Random(5).Next()==726643700;
new Randnm(5).NextDouble()==0.338369840913624-------------------------new Random().NextDouble(); //反复调用该方法时会产生很多相同的随机数Random r=new Random();
r.NextDouble(); //反复调用该方法时产生的随机数不同从2可以看出3,因为没有新的实例.
Next()方法得到新的随机数后会更新随机种子
Random()就是用当前开机时间作为随机种子(Environment.TickCount毫秒为单位)
这样,只要是在同一个毫秒构造的Random实例,随机种子就一样
new Random().NextDouble();
new Random().NextDouble();
这两个语句执行的时间在一毫秒内,随机种子就一样所以结果一样
Random r = new Random().NextDouble();
r.NextDouble();
这两个语句执行的时间也在一毫秒内,但在NextDouble()执行后随机种子被更新了(不是通过时间计算,是通过上一次种子计算)
public class Random
{
// Fields
private int inext;
private int inextp;
private const int MBIG = 0x7fffffff;
private const int MSEED = 0x9a4ec86;
private const int MZ = 0;
private int[] SeedArray; // Methods
public Random() : this(Environment.TickCount)
{
} public Random(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) ? 1 : 0) != 0)
{
num = -num;
}
double num2 = num;
num2 += 2147483646;
return (num2 / 4294967293);
} private int InternalSample()
{
int index = this.inext;
int inextp = this.inextp;
if (++index >= 0x38)
{
index = 1;
}
if (++inextp >= 0x38)
{
inextp = 1;
}
int num = this.SeedArray[index] - this.SeedArray[inextp];
if (num < 0)
{
num += 0x7fffffff;
}
this.SeedArray[index] = num;
this.inext = index;
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", string.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("ArgumentOutOfRange_MustBePositive"), new object[] { "maxValue" }));
}
return (int) (this.Sample() * maxValue);
} public virtual int Next(int minValue, int maxValue)
{
if (minValue > maxValue)
{
throw new ArgumentOutOfRangeException("minValue", string.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Argument_MinMaxValue"), new object[] { "minValue", "maxValue" }));
}
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);
}
}