Using the Random Class
随机类的使用
In this article well be going over how to use the Random class found in the System Namespace. The Random class can be used to generate random numbers a number of different ways and in this article we will go though most of them. In the first part of the article well be discussing how to initialize a new instance of the Random class. Then in the second half of the article we will be going over 3 of its most useful methods: Next, NextBytes, and NextDouble.
在这篇文章中我们将讨论Random类的使用。Random类可以产生一个随机数,这篇文章我们将对这个进行研究。在第一部分,我们将论述如何初始化一个随机类的实列。然后,我们将论述它的三个重要的方法:Next, NextBytes, 和 NextDouble。
Initializing an Instance of the Random Class
初始化一个Random类的实列
Before we get into the different constructors for the Random class I want to discuss what a Seed is. The definition of a Seed is: A number used to calculate a starting value for a number sequence. What this means is, if you want to generate a random number that is not less than 50 then you want yours Seed to be 50.
在进入论述构造随机类之前,我们先讨论种子(Seed)的问题。种子的定义是:用于定义数列的开始值的数字。如果你想产生一个不小于50的随机数,你的种子应该是50。
★ 说明:原文有问题,正确理解应该是:
种子的定义就是:用于定义产生的随机数列的参数,同一台机子,每个种子产生同样的随机数列。(可以参看下面的范列)
The reason I wanted to quickly go over what a Seed was is because you will need to know what it is to understand how the constructor of the Random class determines what the seed is! The first overload for the Random class expects no parameters and uses a time dependent Seed value. The second overload expects an integer as a parameter. This integer value will be used as the Seed.
我们复习种子的原因是:种子是构造随机类实列的基础!第一个随机类实列没有任何参数,使用时间作为默认参数。第二个使用一个整数作为参数,这个整数将被作为种子。
Code Example:
代码列子:
1. Random RA = new Random();
2. Random RA = new Random(15);
The numbers generated from the Random class are on random to a degree. If you use the same Seed value the same series of numbers will be returned. For instance, say you use 15 as the Seed value. You will receive this series of numbers over and over again for the first two values!
从随机类产生的随机数是随机生成的。如果你使用同样的种子值,返回的随机数数列将是同样的。举列来说,你使用15作为种子,每次返回的随机数数列都是一样的。
Code Example:
代码范列:
<script Language="C#" Runat="Server">
protected void Page_Load(Object sender, EventArgs e){
if (IsPostBack) {
Random ra = new Random(15);
int num = ra.Next();
VALUES.Text = VALUES.Text + "<BR>" + num.ToString();
num = ra.Next();
VALUES.Text = VALUES.Text + "<BR>" + num.ToString();
}
}
</script>
<HTML>
<BODY>
<FORM RUNAT="SERVER">
<ASP:LABEL RUNAT="SERVER" ID="VALUES" MaintainState="True"/>
<BR>
<ASP:Button RUNAT="SERVER" TEXT="SUBMIT" />
</FORM>
</BODY>
</HTML>
Random Numbers Generated:
产生的随机数是:
1208223655 469449854
1208223655 469449854
As you can see you receive the same numbers for the first Random number and second Random number generated over and over again.
就象你看到的那样,每次提交产生的随机数都是一样的。
You can resolve this issue by using a method Microsoft recommends.Using the Systems Time as the seed value. Although, you can still run into problems here if the clocks speed on the computer which is very fast because the time may not change from one instance creation to another. Here is a great example found in the .NET SDK Help files to over come this problem.
微软推荐的解决方案是:使用系统时间作为种子。当然,在计算机运算非常快的情况下,每次进入程序实列的时间一样的话,还是会产生这个问题的。在.NET SDK帮助中有一个比较经典的范列,如下:
Code Example:
代码范列:
<script Language="C#" Runat="Server">
protected void Page_Load(Object sender, EventArgs e){
Random Rnd1 = new Random(unchecked((int)DateTime.Now.Ticks));
Random Rnd1a = new Random(unchecked((int)DateTime.Now.Ticks));
Response.Write(Rnd1.Next().ToString());
Response.Write("<BR>");
Response.Write(Rnd1a.Next().ToString());
Response.Write("<BR>");
Random Rnd2 = new Random(~unchecked((int)DateTime.Now.Ticks));
Random Rnd2a = new Random(~unchecked((int)DateTime.Now.Ticks));
Response.Write(Rnd2.Next().ToString());
Response.Write("<BR>");
Response.Write(Rnd2a.Next().ToString());
}
</script>
You'll notice that Rnd1 and Rnd1a are identical, as with Rnd2 and Rnd2a - this is because the same algorithm is used to get their seed values. Using the bitwise operator ~ in Rnd2 & Rnd2a changes the resulting integers value, hence changing the seed value! For those who don't know using unchecked for an arithmetic equation trucates the result if it is out of the range of the resulting data type.
你可以注意到Rnd1和Rnd1a是一样的,就像Rnd2 和 Rnd2a一样的。这是因为他们采用的同样的运算去得到种子的值(运算法则一样,时间间隔没有)。在随机数的种子计算中使用bitwise 运算符 ~来改变种子值。另外要注意,不要运算结果超出范围(这里好像都是废话)。
Next, NextBytes, and NextDouble Methods
Next, NextBytes, 和 NextDouble方法
Now that we have seen how to construct the Random class, lets look at some of the methods we can use to generate random numbers. The first method I want to get into is the Next method. The Next method is used after the Random class has been initialized and is used to return the actual random number that is generated. You have seen me use this in some of the previous examples. There are three overloads for the Next method. The first takes no parameters, the second, takes one parameter that should be an integer. This value specifies the maximum value the returned random number should be. The third overload for the Next method expects two integer values. The first value designates the minimum value acceptable for the returned random number, and the second integer the maximum. So lets take a look at all three:
我们已经看到了如何构造一个随机类,下面看随机类的一些常用的方法。首先介绍的是Next 方法。Next用在已经的随机类初始化后,产生随机数。前面的列子你可以看到它的一个应用。调用Next有三种方式:第一种,不带任何参数;第二种,带一个整数参数,这个参数是返回随机数的最大值;第三种,带两个整数参数,前一个参数是返回随机数的最小值,后一个是返回随机数的最大值;我们可以看下面的代码范列:
Code Example:
代码范列:
<script Language="C#" Runat="Server">
protected void Page_Load(Object sender, EventArgs e){
Random Rnd1 = new Random();
int num1 = Rnd1.Next();
int num2 = Rnd1.Next(1);
int num3 = Rnd1.Next(2, 3);
Response.Write(num1.ToString());
Response.Write("<BR>");
Response.Write(num2.ToString());
Response.Write("<BR>");
Response.Write(num3.ToString());
}
</script>
In this example num1 will be different nearly every time because its seed is generated by the system time. Num2 will always be 0 because 1 is always the max value. Finally, 2 will always be the value of num3 because the minvalue is 2 and the maxvalue is 3.
在这个列子中,num1每次是不同的的,因为它的种子是系统时间;Num2 一直是0,是因为1是允许的最大值;最后一个一直是2,是因为2是最小限制,3是最大限制。
The next method I want to talk about is the NextBytes method. The NextBytes method expects one parameter, an array of bytes. The NextBytes method fills this array of bytes with Random numbers. The following example demonstrates how to use the NextBytes method:
下面我们将讨论NextBytes方法。NextBytes 方法需要一个参数,一个byte数组。NextBytes 方法用随机数添充这个数组。下面的列子演示了NextBytes 的用法。
Code Example:
代码范列:
<script Language="C#" Runat="Server">
protected void Page_Load(Object sender, EventArgs e){
Random Rnd1 = new Random();
byte[] bArray = new byte[10];
Rnd1.NextBytes(bArray);
for (int i = 0; i < bArray.Length; i ++){
Response.Write("<BR>");
Response.Write(bArray[i].ToString());
}
}
</script>
The final method I want to talk about is the NextDouble method. The NextDouble method has no parameters and returns a double precision point number <= .0 and > 1.0. An example of the NextDouble method can be found below:
最后我们讨论NextDouble 方法。NextDouble 方法没有参数,返回一个double精度的浮点数(),下面是列子。
Code Example:
<script Language="C#" Runat="Server">
protected void Page_Load(Object sender, EventArgs e){
Random Rnd1 = new Random();
double dbl = Rnd1.NextDouble();
Response.Write(dbl.ToString());
Response.Write("<BR>");
dbl = Rnd1.NextDouble();
Response.Write(dbl.ToString());
}
</script>
Conclusion
总结
As you can see by my examples the Random class is quite easy to use, but at the same time kind of tricky. Using the Random class to generate a random number by default doesn't mean you will receive a random number for every situation, but by using some very easy methods such as Seed values and different algorithms.
通过列子你可以看到随机数的使用是很简单的。但是一定要注意避免每次产生的随机数是同一个数列,这时候要用改变种子值,和种子运算法则来改变随机队列。
说明:
1、以上方法,beta 1 和 beta 2都适用。
2、本文出处: