Browse Source

RandomExtensions.NextBigIntegerSequence

pull/893/head
埃博拉酱 5 years ago
parent
commit
74470f90ba
  1. 18
      src/Numerics.Tests/Random/RandomExtensionTests.cs
  2. 32
      src/Numerics/Random/RandomExtensions.cs

18
src/Numerics.Tests/Random/RandomExtensionTests.cs

@ -29,6 +29,8 @@
using MathNet.Numerics.Random;
using NUnit.Framework;
using System.Numerics;
using System.Collections.Generic;
namespace MathNet.Numerics.UnitTests.Random
{
@ -48,6 +50,22 @@ namespace MathNet.Numerics.UnitTests.Random
rnd.NextInt64();
}
/// <summary>
/// Can sample BigInteger
/// </summary>
[Test]
public void CanSampleBigInteger()
{
var rnd = new System.Random(0);
IEnumerator<BigInteger> Sequence = rnd.NextBigIntegerSequence((BigInteger)long.MinValue * 3, (BigInteger)long.MaxValue * 3).GetEnumerator();
Sequence.MoveNext();
System.Console.WriteLine(Sequence.Current);
Sequence.MoveNext();
System.Console.WriteLine(Sequence.Current);
Sequence.MoveNext();
System.Console.WriteLine(Sequence.Current);
}
/// <summary>
/// Can sample full range int32.
/// </summary>

32
src/Numerics/Random/RandomExtensions.cs

@ -29,6 +29,8 @@
using System;
using System.Collections.Generic;
using System.Numerics;
using System.Linq;
namespace MathNet.Numerics.Random
{
@ -167,7 +169,7 @@ namespace MathNet.Numerics.Random
}
/// <summary>
/// Returns an infinite sequence of uniform random numbers greater than or equal to 0.0 and less than 1.0.
/// Returns an infinite sequence of uniform random 32-bit signed integers within the specified range.
/// </summary>
/// <remarks>
/// This extension is thread-safe if and only if called on an random number
@ -191,6 +193,34 @@ namespace MathNet.Numerics.Random
}
}
/// <summary>
/// Returns an infinite sequence of uniform random <see cref="System.Numerics.BigInteger"/> within the specified range.
/// </summary>
/// <remarks>
/// This extension is thread-safe if and only if called on an random number
/// generator provided by Math.NET Numerics or derived from the RandomSource class.
/// </remarks>
public static IEnumerable<BigInteger> NextBigIntegerSequence(this System.Random rnd, BigInteger minInclusive, BigInteger maxExclusive)
{
BigInteger AbsoluteRange = maxExclusive - minInclusive;
int NumBytes = (int)Math.Ceiling(BigInteger.Log(AbsoluteRange, byte.MaxValue) * 2);
byte[] ByteSequence = Enumerable.Repeat(byte.MaxValue, NumBytes + 1).ToArray();
ByteSequence[NumBytes] = 0;
BigInteger RandomNumber = new BigInteger(ByteSequence);
BigInteger ValidRange = RandomNumber - RandomNumber % AbsoluteRange;
while(true)
{
do
{
rnd.NextBytes(ByteSequence);
ByteSequence[NumBytes] = 0;
RandomNumber = new BigInteger(ByteSequence);
}
while (RandomNumber >= ValidRange);
yield return RandomNumber % AbsoluteRange + minInclusive;
}
}
/// <summary>
/// Returns a nonnegative random number less than <see cref="Int64.MaxValue"/>.
/// </summary>

Loading…
Cancel
Save