diff options
Diffstat (limited to 'src/mscorlib/src/System/Random.cs')
-rw-r--r-- | src/mscorlib/src/System/Random.cs | 74 |
1 files changed, 55 insertions, 19 deletions
diff --git a/src/mscorlib/src/System/Random.cs b/src/mscorlib/src/System/Random.cs index adede6a101..f5941d6718 100644 --- a/src/mscorlib/src/System/Random.cs +++ b/src/mscorlib/src/System/Random.cs @@ -11,13 +11,14 @@ ** ===========================================================*/ namespace System { - + using System; using System.Runtime; using System.Runtime.CompilerServices; using System.Globalization; using System.Diagnostics.Contracts; -[System.Runtime.InteropServices.ComVisible(true)] + + [System.Runtime.InteropServices.ComVisible(true)] [Serializable] public class Random { // @@ -46,13 +47,19 @@ namespace System { // // Constructors // - + + /*========================================================================================= + **Action: Initializes a new instance of the Random class, using a default seed value + ===========================================================================================*/ public Random() - : this(Environment.TickCount) { + : this(GenerateSeed()) { } - + + /*========================================================================================= + **Action: Initializes a new instance of the Random class, using a specified seed value + ===========================================================================================*/ public Random(int Seed) { - int ii; + int ii = 0; int mj, mk; //Initialize our Seed array. @@ -61,7 +68,7 @@ namespace System { SeedArray[55]=mj; mk=1; for (int i=1; i<55; i++) { //Apparently the range [1..55] is special (Knuth) and so we're wasting the 0'th position. - ii = (21*i)%55; + if ((ii += 21) >= 55) ii -= 55; SeedArray[ii]=mk; mk = mj - mk; if (mk<0) mk+=MBIG; @@ -69,19 +76,21 @@ namespace System { } for (int k=1; k<5; k++) { for (int i=1; i<56; i++) { - SeedArray[i] -= SeedArray[1+(i+30)%55]; - if (SeedArray[i]<0) SeedArray[i]+=MBIG; + int n = i + 30; + if (n >= 55) n -= 55; + SeedArray[i] -= SeedArray[1 + n]; + if (SeedArray[i]<0) SeedArray[i]+=MBIG; } } inext=0; inextp = 21; Seed = 1; } - + // // Package Private Methods // - + /*====================================Sample==================================== **Action: Return a new random number [0..1) and reSeed the Seed array. **Returns: A double [0..1) @@ -115,11 +124,41 @@ namespace System { return retVal; } + + [ThreadStatic] + private static Random t_threadRandom; + private static readonly Random s_globalRandom = new Random(GenerateGlobalSeed()); + + /*=====================================GenerateSeed===================================== + **Returns: An integer that can be used as seed values for consecutively + creating lots of instances on the same thread within a short period of time. + ========================================================================================*/ + private static int GenerateSeed() { + Random rnd = t_threadRandom; + if (rnd == null) { + int seed; + lock (s_globalRandom) { + seed = s_globalRandom.Next(); + } + rnd = new Random(seed); + t_threadRandom = rnd; + } + return rnd.Next(); + } + + /*==================================GenerateGlobalSeed==================================== + **Action: Creates a number to use as global seed. + **Returns: An integer that is safe to use as seed values for thread-local seed generators. + ==========================================================================================*/ + private static int GenerateGlobalSeed() { + return Guid.NewGuid().GetHashCode(); + } + // // Public Instance Methods // - - + + /*=====================================Next===================================== **Returns: An int [0..Int32.MaxValue) **Arguments: None @@ -156,7 +195,7 @@ namespace System { ==============================================================================*/ public virtual int Next(int minValue, int maxValue) { if (minValue>maxValue) { - throw new ArgumentOutOfRangeException("minValue",Environment.GetResourceString("Argument_MinMaxValue", "minValue", "maxValue")); + throw new ArgumentOutOfRangeException(nameof(minValue),Environment.GetResourceString("Argument_MinMaxValue", nameof(minValue), nameof(maxValue))); } Contract.EndContractBlock(); @@ -177,7 +216,7 @@ namespace System { ==============================================================================*/ public virtual int Next(int maxValue) { if (maxValue<0) { - throw new ArgumentOutOfRangeException("maxValue", Environment.GetResourceString("ArgumentOutOfRange_MustBePositive", "maxValue")); + throw new ArgumentOutOfRangeException(nameof(maxValue), Environment.GetResourceString("ArgumentOutOfRange_MustBePositive", nameof(maxValue))); } Contract.EndContractBlock(); return (int)(Sample()*maxValue); @@ -201,14 +240,11 @@ namespace System { **Exceptions: None ==============================================================================*/ public virtual void NextBytes(byte [] buffer){ - if (buffer==null) throw new ArgumentNullException("buffer"); + if (buffer==null) throw new ArgumentNullException(nameof(buffer)); Contract.EndContractBlock(); for (int i=0; i<buffer.Length; i++) { buffer[i]=(byte)(InternalSample()%(Byte.MaxValue+1)); } } } - - - } |