Browse Source

Random: improved fallbacks on zero-minInclusive integer sampling

netstandard
Christoph Ruegg 10 years ago
parent
commit
484f1e44f2
  1. 2
      src/Numerics/Random/CryptoRandomSource.cs
  2. 86
      src/Numerics/Random/RandomSource.cs
  3. 5
      src/Numerics/Random/SystemRandomSource.cs

2
src/Numerics/Random/CryptoRandomSource.cs

@ -110,7 +110,7 @@ namespace MathNet.Numerics.Random
var bytes = new byte[4];
_crypto.GetBytes(bytes);
uint uint32 = BitConverter.ToUInt32(bytes, 0);
int int31 = (int)uint32 >> 1;
int int31 = (int)(uint32 >> 1);
if (int31 == int.MaxValue)
{
return DoSampleInteger();

86
src/Numerics/Random/RandomSource.cs

@ -159,11 +159,11 @@ namespace MathNet.Numerics.Random
{
lock (_lock)
{
return DoSampleInteger(0, maxExclusive);
return DoSampleInteger(maxExclusive);
}
}
return DoSampleInteger(0, maxExclusive);
return DoSampleInteger(maxExclusive);
}
/// <summary>
@ -182,9 +182,14 @@ namespace MathNet.Numerics.Random
throw new ArgumentException(Resources.ArgumentMinValueGreaterThanMaxValue);
}
if (maxExclusive == int.MaxValue && minInclusive == 0)
if (minInclusive == 0)
{
return Next();
if (maxExclusive == int.MaxValue)
{
return Next();
}
return Next(maxExclusive);
}
if (_threadSafe)
@ -234,6 +239,38 @@ namespace MathNet.Numerics.Random
return values;
}
/// <summary>
/// Fills an array with random numbers within a specified range.
/// </summary>
/// <param name="values">The array to fill with random values.</param>
/// <param name="maxExclusive">The exclusive upper bound of the random number returned.</param>
public void NextInt32s(int[] values, int maxExclusive)
{
if (maxExclusive == int.MaxValue)
{
NextInt32s(values);
return;
}
if (_threadSafe)
{
lock (_lock)
{
for (var i = 0; i < values.Length; i++)
{
values[i] = DoSampleInteger(maxExclusive);
}
}
}
else
{
for (var i = 0; i < values.Length; i++)
{
values[i] = DoSampleInteger(maxExclusive);
}
}
}
/// <summary>
/// Fills an array with random numbers within a specified range.
/// </summary>
@ -253,6 +290,18 @@ namespace MathNet.Numerics.Random
return;
}
if (minInclusive == 0)
{
if (maxExclusive == int.MaxValue)
{
NextInt32s(values);
return;
}
NextInt32s(values, maxExclusive);
return;
}
if (_threadSafe)
{
lock (_lock)
@ -389,16 +438,6 @@ namespace MathNet.Numerics.Random
return (int)(DoSample() * int.MaxValue);
}
/// <summary>
/// Returns a random 32-bit signed integer within the specified range.
/// </summary>
/// <param name="minInclusive">The inclusive lower bound of the random number returned.</param>
/// <param name="maxExclusive">The exclusive upper bound of the random number returned. <paramref name="maxExclusive"/> must be greater than or equal to <paramref name="minInclusive"/>.</param>
protected virtual int DoSampleInteger(int minInclusive, int maxExclusive)
{
return (int)(DoSample()*(maxExclusive - minInclusive)) + minInclusive;
}
/// <summary>
/// Fills the elements of a specified array of bytes with random numbers in full range, including zero and 255 (<see cref="F:System.Byte.MaxValue"/>).
/// </summary>
@ -409,5 +448,24 @@ namespace MathNet.Numerics.Random
buffer[i] = (byte)(DoSampleInteger() % 256);
}
}
/// <summary>
/// Returns a random 32-bit signed integer within the specified range.
/// </summary>
/// <param name="maxExclusive">The exclusive upper bound of the random number returned.</param>
protected virtual int DoSampleInteger(int maxExclusive)
{
return (int)(DoSample() * maxExclusive);
}
/// <summary>
/// Returns a random 32-bit signed integer within the specified range.
/// </summary>
/// <param name="minInclusive">The inclusive lower bound of the random number returned.</param>
/// <param name="maxExclusive">The exclusive upper bound of the random number returned. <paramref name="maxExclusive"/> must be greater than or equal to <paramref name="minInclusive"/>.</param>
protected virtual int DoSampleInteger(int minInclusive, int maxExclusive)
{
return DoSampleInteger(maxExclusive - minInclusive) + minInclusive;
}
}
}

5
src/Numerics/Random/SystemRandomSource.cs

@ -126,6 +126,11 @@ namespace MathNet.Numerics.Random
return _random.Next();
}
protected override int DoSampleInteger(int maxExclusive)
{
return _random.Next(maxExclusive);
}
/// <summary>
/// Returns a random 32-bit signed integer within the specified range.
/// </summary>

Loading…
Cancel
Save