刚才不知怎么突然想到这个问题。先把C#中Random类的代码贴过来,回头好好看看:
1 /**//*============================================================
2 **
3 ** Class: Random.cs
4 **
5 **
6 **
7 ** Purpose: A random number generator.
8 **
9 ** Date: July 8, 1998
10 **
11 ===========================================================*/
12 namespace System {
13
14 using System;
15 using System.Runtime.CompilerServices;
16 /**//// <include file='doc\Random.uex' path='docs/doc[@for="Random"]/*' />
17 [Serializable()] public class Random {
18 //
19 // Private Constants
20 //
21 private const int MBIG = Int32.MaxValue;
22 private const int MSEED = 161803398;
23 private const int MZ = 0;
24
25
26 //
27 // Member Variables
28 //
29 private int inext, inextp;
30 private int[] SeedArray = new int[56];
31
32 /**//// <include file='doc\Random.uex' path='docs/doc[@for="Random.Random"]/*' />
33 public Random()
34 : this(Environment.TickCount) {
35 }
36
37 /**//// <include file='doc\Random.uex' path='docs/doc[@for="Random.Random1"]/*' />
38 public Random(int Seed) {
39 int ii;
40 int mj, mk;
41
42 //Initialize our Seed array.
43 //This algorithm comes from Numerical Recipes in C (2nd Ed.)
44 mj = MSEED - Math.Abs(Seed);
45 SeedArray[55]=mj;
46 mk=1;
47 for (int i=1; i<55; i++) { //Apparently the range [1..55] is special (Knuth) and
48 //so we're wasting the 0'th position.
49 ii = (21*i)%55;
50 SeedArray[ii]=mk;
51 mk = mj - mk;
52 if (mk<0) mk+=MBIG;
53 mj=SeedArray[ii];
54 }
55 for (int k=1; k<5; k++) {
56 for (int i=1; i<56; i++) {
57 SeedArray[i] -= SeedArray[1+(i+30)%55];
58 if (SeedArray[i]<0) SeedArray[i]+=MBIG;
59 }
60 }
61 inext=0;
62 inextp = 21;
63 Seed = 1;
64 }
65
66 //
67 // Package Private Methods
68 //
69
70 /**//*====================================Sample====================================
71 **Action: Return a new random number [0..1) and reSeed the Seed array.
72 **Returns: A double [0..1)
73 **Arguments: None
74 **Exceptions: None
75 ==============================================================================*/
76 /**//// <include file='doc\Random.uex' path='docs/doc[@for="Random.Sample"]/*' />
77 protected virtual double Sample() {
78 int retVal;
79 int locINext = inext;
80 int locINextp = inextp;
81
82 if (++locINext >=56) locINext=1;
83 if (++locINextp>= 56) locINextp = 1;
84
85 retVal = SeedArray[locINext]-SeedArray[locINextp];
86
87 if (retVal<0) retVal+=MBIG;
88
89 SeedArray[locINext]=retVal;
90
91 inext = locINext;
92 inextp = locINextp;
93
94 //Including this division at the end gives us significantly improved
95 //random number distribution.
96 return (retVal*(1.0/MBIG));
97 }
98
99 //
100 // Public Instance Methods
101 //
102
103
104 /**//*=====================================Next=====================================
105 **Returns: An int [0.._int4.MaxValue)
106 **Arguments: None
107 **Exceptions: None.
108 ==============================================================================*/
109 /**//// <include file='doc\Random.uex' path='docs/doc[@for="Random.Next"]/*' />
110 public virtual int Next() {
111 return (int)(Sample()*Int32.MaxValue);
112 }
113
114 /**//*=====================================Next=====================================
115 **Returns: An int [minvalue..maxvalue)
116 **Arguments: minValue -- the least legal value for the Random number.
117 ** maxValue -- the greatest legal return value.
118 **Exceptions: None.
119 ==============================================================================*/
120 /**//// <include file='doc\Random.uex' path='docs/doc[@for="Random.Next1"]/*' />
121 public virtual int Next(int minValue, int maxValue) {
122 if (minValue>maxValue) {
123 throw new ArgumentOutOfRangeException("minValue",String.Format(Environment.GetResourceString("Argument_MinMaxValue"), "minValue", "maxValue"));
124 }
125
126 int range = (maxValue-minValue);
127
128 //This is the case where we flipped around (e.g. MaxValue-MinValue);
129 if (range<0) {
130 long longRange = (long)maxValue-(long)minValue;
131 return (int)(((long)(Sample()*((double)longRange)))+minValue);
132 }
133
134 return ((int)(Sample()*(range)))+minValue;
135 }
136
137
138 /**//*=====================================Next=====================================
139 **Returns: An int [0..maxValue)
140 **Arguments: maxValue -- the greatest legal return value.
141 **Exceptions: None.
142 ==============================================================================*/
143 /**//// <include file='doc\Random.uex' path='docs/doc[@for="Random.Next2"]/*' />
144 public virtual int Next(int maxValue) {
145 if (maxValue<0) {
146 throw new ArgumentOutOfRangeException("maxValue", String.Format(Environment.GetResourceString("ArgumentOutOfRange_MustBePositive"), "maxValue"));
147 }
148 return (int)(Sample()*maxValue);
149 }
150
151
152 /**//*=====================================Next=====================================
153 **Returns: A double [0..1)
154 **Arguments: None
155 **Exceptions: None
156 ==============================================================================*/
157 /**//// <include file='doc\Random.uex' path='docs/doc[@for="Random.NextDouble"]/*' />
158 public virtual double NextDouble() {
159 return Sample();
160 }
161
162
163 /**//*==================================NextBytes===================================
164 **Action: Fills the byte array with random bytes [0..0x7f]. The entire array is filled.
165 **Returns:Void
166 **Arugments: buffer -- the array to be filled.
167 **Exceptions: None
168 ==============================================================================*/
169 /**//// <include file='doc\Random.uex' path='docs/doc[@for="Random.NextBytes"]/*' />
170 public virtual void NextBytes(byte [] buffer){
171 if (buffer==null) throw new ArgumentNullException("buffer");
172 for (int i=0; i<buffer.Length; i++) {
173 buffer[i]=(byte)(Sample()*(Byte.MaxValue+1));
174 }
175 }
176 }
177
178 }
2 **
3 ** Class: Random.cs
4 **
5 **
6 **
7 ** Purpose: A random number generator.
8 **
9 ** Date: July 8, 1998
10 **
11 ===========================================================*/
12 namespace System {
13
14 using System;
15 using System.Runtime.CompilerServices;
16 /**//// <include file='doc\Random.uex' path='docs/doc[@for="Random"]/*' />
17 [Serializable()] public class Random {
18 //
19 // Private Constants
20 //
21 private const int MBIG = Int32.MaxValue;
22 private const int MSEED = 161803398;
23 private const int MZ = 0;
24
25
26 //
27 // Member Variables
28 //
29 private int inext, inextp;
30 private int[] SeedArray = new int[56];
31
32 /**//// <include file='doc\Random.uex' path='docs/doc[@for="Random.Random"]/*' />
33 public Random()
34 : this(Environment.TickCount) {
35 }
36
37 /**//// <include file='doc\Random.uex' path='docs/doc[@for="Random.Random1"]/*' />
38 public Random(int Seed) {
39 int ii;
40 int mj, mk;
41
42 //Initialize our Seed array.
43 //This algorithm comes from Numerical Recipes in C (2nd Ed.)
44 mj = MSEED - Math.Abs(Seed);
45 SeedArray[55]=mj;
46 mk=1;
47 for (int i=1; i<55; i++) { //Apparently the range [1..55] is special (Knuth) and
48 //so we're wasting the 0'th position.
49 ii = (21*i)%55;
50 SeedArray[ii]=mk;
51 mk = mj - mk;
52 if (mk<0) mk+=MBIG;
53 mj=SeedArray[ii];
54 }
55 for (int k=1; k<5; k++) {
56 for (int i=1; i<56; i++) {
57 SeedArray[i] -= SeedArray[1+(i+30)%55];
58 if (SeedArray[i]<0) SeedArray[i]+=MBIG;
59 }
60 }
61 inext=0;
62 inextp = 21;
63 Seed = 1;
64 }
65
66 //
67 // Package Private Methods
68 //
69
70 /**//*====================================Sample====================================
71 **Action: Return a new random number [0..1) and reSeed the Seed array.
72 **Returns: A double [0..1)
73 **Arguments: None
74 **Exceptions: None
75 ==============================================================================*/
76 /**//// <include file='doc\Random.uex' path='docs/doc[@for="Random.Sample"]/*' />
77 protected virtual double Sample() {
78 int retVal;
79 int locINext = inext;
80 int locINextp = inextp;
81
82 if (++locINext >=56) locINext=1;
83 if (++locINextp>= 56) locINextp = 1;
84
85 retVal = SeedArray[locINext]-SeedArray[locINextp];
86
87 if (retVal<0) retVal+=MBIG;
88
89 SeedArray[locINext]=retVal;
90
91 inext = locINext;
92 inextp = locINextp;
93
94 //Including this division at the end gives us significantly improved
95 //random number distribution.
96 return (retVal*(1.0/MBIG));
97 }
98
99 //
100 // Public Instance Methods
101 //
102
103
104 /**//*=====================================Next=====================================
105 **Returns: An int [0.._int4.MaxValue)
106 **Arguments: None
107 **Exceptions: None.
108 ==============================================================================*/
109 /**//// <include file='doc\Random.uex' path='docs/doc[@for="Random.Next"]/*' />
110 public virtual int Next() {
111 return (int)(Sample()*Int32.MaxValue);
112 }
113
114 /**//*=====================================Next=====================================
115 **Returns: An int [minvalue..maxvalue)
116 **Arguments: minValue -- the least legal value for the Random number.
117 ** maxValue -- the greatest legal return value.
118 **Exceptions: None.
119 ==============================================================================*/
120 /**//// <include file='doc\Random.uex' path='docs/doc[@for="Random.Next1"]/*' />
121 public virtual int Next(int minValue, int maxValue) {
122 if (minValue>maxValue) {
123 throw new ArgumentOutOfRangeException("minValue",String.Format(Environment.GetResourceString("Argument_MinMaxValue"), "minValue", "maxValue"));
124 }
125
126 int range = (maxValue-minValue);
127
128 //This is the case where we flipped around (e.g. MaxValue-MinValue);
129 if (range<0) {
130 long longRange = (long)maxValue-(long)minValue;
131 return (int)(((long)(Sample()*((double)longRange)))+minValue);
132 }
133
134 return ((int)(Sample()*(range)))+minValue;
135 }
136
137
138 /**//*=====================================Next=====================================
139 **Returns: An int [0..maxValue)
140 **Arguments: maxValue -- the greatest legal return value.
141 **Exceptions: None.
142 ==============================================================================*/
143 /**//// <include file='doc\Random.uex' path='docs/doc[@for="Random.Next2"]/*' />
144 public virtual int Next(int maxValue) {
145 if (maxValue<0) {
146 throw new ArgumentOutOfRangeException("maxValue", String.Format(Environment.GetResourceString("ArgumentOutOfRange_MustBePositive"), "maxValue"));
147 }
148 return (int)(Sample()*maxValue);
149 }
150
151
152 /**//*=====================================Next=====================================
153 **Returns: A double [0..1)
154 **Arguments: None
155 **Exceptions: None
156 ==============================================================================*/
157 /**//// <include file='doc\Random.uex' path='docs/doc[@for="Random.NextDouble"]/*' />
158 public virtual double NextDouble() {
159 return Sample();
160 }
161
162
163 /**//*==================================NextBytes===================================
164 **Action: Fills the byte array with random bytes [0..0x7f]. The entire array is filled.
165 **Returns:Void
166 **Arugments: buffer -- the array to be filled.
167 **Exceptions: None
168 ==============================================================================*/
169 /**//// <include file='doc\Random.uex' path='docs/doc[@for="Random.NextBytes"]/*' />
170 public virtual void NextBytes(byte [] buffer){
171 if (buffer==null) throw new ArgumentNullException("buffer");
172 for (int i=0; i<buffer.Length; i++) {
173 buffer[i]=(byte)(Sample()*(Byte.MaxValue+1));
174 }
175 }
176 }
177
178 }