From 74470f90bac33910fb25340eb71c993d0af552a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=9F=83=E5=8D=9A=E6=8B=89=E9=85=B1?= Date: Fri, 7 Jan 2022 14:27:40 +0800 Subject: [PATCH] RandomExtensions.NextBigIntegerSequence --- .../Random/RandomExtensionTests.cs | 18 +++++++++++ src/Numerics/Random/RandomExtensions.cs | 32 ++++++++++++++++++- 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/src/Numerics.Tests/Random/RandomExtensionTests.cs b/src/Numerics.Tests/Random/RandomExtensionTests.cs index 99c732c2..5bb84713 100644 --- a/src/Numerics.Tests/Random/RandomExtensionTests.cs +++ b/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(); } + /// + /// Can sample BigInteger + /// + [Test] + public void CanSampleBigInteger() + { + var rnd = new System.Random(0); + IEnumerator 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); + } + /// /// Can sample full range int32. /// diff --git a/src/Numerics/Random/RandomExtensions.cs b/src/Numerics/Random/RandomExtensions.cs index c351e3d8..0ba53982 100644 --- a/src/Numerics/Random/RandomExtensions.cs +++ b/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 } /// - /// 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. /// /// /// This extension is thread-safe if and only if called on an random number @@ -191,6 +193,34 @@ namespace MathNet.Numerics.Random } } + /// + /// Returns an infinite sequence of uniform random within the specified range. + /// + /// + /// 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. + /// + public static IEnumerable 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; + } + } + /// /// Returns a nonnegative random number less than . ///