From 7592ccb50b66368772f42a3d2558db7fe96ab796 Mon Sep 17 00:00:00 2001 From: Jurgen Van Gael Date: Thu, 20 Aug 2009 05:49:27 +0800 Subject: [PATCH] Added extension methods for System.Random that sample additional value types. Signed-off-by: jvangael --- src/Numerics/Numerics.csproj | 1 + src/Numerics/Random/SystemRandomExtensions.cs | 117 ++++++++++++++++++ .../Random/SystemRandomExtensionTests.cs | 65 ++++++++++ src/UnitTests/UnitTests.csproj | 1 + 4 files changed, 184 insertions(+) create mode 100644 src/Numerics/Random/SystemRandomExtensions.cs create mode 100644 src/UnitTests/Random/SystemRandomExtensionTests.cs diff --git a/src/Numerics/Numerics.csproj b/src/Numerics/Numerics.csproj index f240ced1..3897ebf2 100644 --- a/src/Numerics/Numerics.csproj +++ b/src/Numerics/Numerics.csproj @@ -100,6 +100,7 @@ True Resources.resx + diff --git a/src/Numerics/Random/SystemRandomExtensions.cs b/src/Numerics/Random/SystemRandomExtensions.cs new file mode 100644 index 00000000..fb193079 --- /dev/null +++ b/src/Numerics/Random/SystemRandomExtensions.cs @@ -0,0 +1,117 @@ +// +// Math.NET Numerics, part of the Math.NET Project +// http://mathnet.opensourcedotnet.info +// +// Copyright (c) 2009 Math.NET +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +namespace MathNet.Numerics.Random +{ + using System; + using System.Collections.Generic; + using Properties; + + public static class SystemRandomExtensions + { + /// + /// Returns a nonnegative random number less than . + /// + /// + /// A 64-bit signed integer greater than or equal to 0, and less than ; that is, + /// the range of return values includes 0 but not . + /// + /// + public static long NextInt64(this System.Random rnd) + { + byte[] buffer = new byte[sizeof(Int64)]; + rnd.NextBytes(buffer); + long candidate = BitConverter.ToInt64(buffer, 0); + + // wrap negative numbers around, mapping every negative number to a distinct nonnegative number + // MinValue -> 0, -1 -> MaxValue + candidate &= Int64.MaxValue; + + // skip candidate if it is MaxValue. Recursive since rare. + return (candidate == Int64.MaxValue) ? rnd.NextInt64() : candidate; + } + + /// + /// Returns a random number of the full Int32 range. + /// + /// + /// A 32-bit signed integer of the full range, including 0, negative numbers, + /// and . + /// + /// + public static int NextFullRangeInt32(this System.Random rnd) + { + byte[] buffer = new byte[sizeof(Int32)]; + rnd.NextBytes(buffer); + return BitConverter.ToInt32(buffer, 0); + } + + /// + /// Returns a random number of the full Int64 range. + /// + /// + /// A 64-bit signed integer of the full range, including 0, negative numbers, + /// and . + /// + /// + public static long NextFullRangeInt64(this System.Random rnd) + { + byte[] buffer = new byte[sizeof(Int64)]; + rnd.NextBytes(buffer); + return BitConverter.ToInt64(buffer, 0); + } + + /// + /// Returns a nonnegative decimal floating point random number less than 1.0. + /// + /// + /// A decimal floating point number greater than or equal to 0.0, and less than 1.0; that is, + /// the range of return values includes 0.0 but not 1.0. + /// + public static decimal NextDecimal(this System.Random rnd) + { + decimal candidate; + + // 50.049 % chance that the number is below 1.0. Try until we have one. + // Guarantees that any decimal in the interval can + // indeed be reached, with uniform probability. + do + { + candidate = new Decimal( + rnd.NextFullRangeInt32(), + rnd.NextFullRangeInt32(), + rnd.NextFullRangeInt32(), + false, + 28); + } + while (candidate >= 1.0m); + + return candidate; + } + } +} diff --git a/src/UnitTests/Random/SystemRandomExtensionTests.cs b/src/UnitTests/Random/SystemRandomExtensionTests.cs new file mode 100644 index 00000000..20e066a3 --- /dev/null +++ b/src/UnitTests/Random/SystemRandomExtensionTests.cs @@ -0,0 +1,65 @@ +// +// Math.NET Numerics, part of the Math.NET Project +// http://mathnet.opensourcedotnet.info +// +// Copyright (c) 2009 Math.NET +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +namespace MathNet.Numerics.UnitTests.DistributionTests +{ + using MbUnit.Framework; + using MathNet.Numerics.Random; + + [TestFixture] + public class SystemRandomExtensionTests + { + [Test] + public void CanSampleInt64() + { + var rnd = new System.Random(); + long l = rnd.NextInt64(); + } + + [Test] + public void CanSampleFullRangeInt32() + { + var rnd = new System.Random(); + int l = rnd.NextFullRangeInt32(); + } + + [Test] + public void CanSampleFullRangeInt64() + { + var rnd = new System.Random(); + long l = rnd.NextFullRangeInt64(); + } + + [Test] + public void CanSampleDecimal() + { + var rnd = new System.Random(); + decimal l = rnd.NextDecimal(); + } + } +} diff --git a/src/UnitTests/UnitTests.csproj b/src/UnitTests/UnitTests.csproj index c3364370..b9d2d67b 100644 --- a/src/UnitTests/UnitTests.csproj +++ b/src/UnitTests/UnitTests.csproj @@ -92,6 +92,7 @@ +