diff --git a/build.vc11/mpir.net/mpir.net-tests/mpir.net-tests.csproj b/build.vc11/mpir.net/mpir.net-tests/mpir.net-tests.csproj index a6fd59ca..641f5b35 100644 --- a/build.vc11/mpir.net/mpir.net-tests/mpir.net-tests.csproj +++ b/build.vc11/mpir.net/mpir.net-tests/mpir.net-tests.csproj @@ -118,6 +118,9 @@ HugeIntTests\Math.cs + + HugeIntTests\NumberTheoretic.cs + IntegrationTests\XmlCommentsTests.cs diff --git a/mpir.net/mpir.net-tests/HugeIntTests/NumberTheoretic.cs b/mpir.net/mpir.net-tests/HugeIntTests/NumberTheoretic.cs new file mode 100644 index 00000000..0b884261 --- /dev/null +++ b/mpir.net/mpir.net-tests/HugeIntTests/NumberTheoretic.cs @@ -0,0 +1,55 @@ +/* +Copyright 2014 Alex Dyachenko + +This file is part of the MPIR Library. + +The MPIR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published +by the Free Software Foundation; either version 3 of the License, or (at +your option) any later version. + +The MPIR Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the MPIR Library. If not, see http://www.gnu.org/licenses/. +*/ + +using System; +using System.IO; +using System.Text; +using System.Linq; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace MPIR.Tests.HugeIntTests +{ + [TestClass] + public class NumberTheoretic + { + [TestMethod] + public void IsProbablePrime() + { + using (var a = new HugeInt("622288097498926496141095869268883999563096063592498055290461")) + using (var random = MpirRandom.Default()) + { + Assert.IsTrue(a.IsProbablePrime(random, 10, 0)); + a.Value = a * 2; + Assert.IsFalse(a.IsProbablePrime(random, 10, 0)); + } + } + + [TestMethod] + public void IsLikelyPrime() + { + using (var a = new HugeInt("622288097498926496141095869268883999563096063592498055290461")) + using (var random = MpirRandom.Default()) + { + Assert.IsTrue(a.IsLikelyPrime(random, 0)); + a.Value = a * 2; + Assert.IsFalse(a.IsLikelyPrime(random, 0)); + } + } + } +} diff --git a/mpir.net/mpir.net/HugeInt.cpp b/mpir.net/mpir.net/HugeInt.cpp index 6ebb4649..33adab11 100644 --- a/mpir.net/mpir.net/HugeInt.cpp +++ b/mpir.net/mpir.net/HugeInt.cpp @@ -18,6 +18,7 @@ along with the MPIR Library. If not, see http://www.gnu.org/licenses/. */ #include "Stdafx.h" +#include "Random.h" using namespace System::Runtime::InteropServices; using namespace System::Text; @@ -642,4 +643,18 @@ namespace MPIR } #pragma endregion + + #pragma region number-theoretic + + bool HugeInt::IsProbablePrime(MpirRandom^ random, int probability, mpir_ui pretested) + { + return mpz_probable_prime_p(_value, random->_value, probability, pretested) != 0; + } + + bool HugeInt::IsLikelyPrime(MpirRandom^ random, mpir_ui pretested) + { + return mpz_likely_prime_p(_value, random->_value, pretested) != 0; + } + + #pragma endregion }; \ No newline at end of file diff --git a/mpir.net/mpir.net/HugeInt.h b/mpir.net/mpir.net/HugeInt.h index 73832a32..69eb2300 100644 --- a/mpir.net/mpir.net/HugeInt.h +++ b/mpir.net/mpir.net/HugeInt.h @@ -263,6 +263,7 @@ private ref class Mpir##name##Expression : base namespace MPIR { + ref class MpirRandom; ref class HugeInt; ref class MpirDivideExpression; ref class MpirDivideUiExpression; @@ -1993,6 +1994,38 @@ namespace MPIR size_t GetLimb(mp_size_t index) { return mpz_getlimbn(_value, index); } #pragma endregion + + #pragma region number-theoretic + + /// + /// Determines whether the number is a probable prime with the chance of error being at most 1 in 2^. + /// This function does some trial divisions to speed up the average case, then some probabilistic + /// primality tests to achieve the desired level of error. + /// This function interface is preliminary and may change in the future. + /// + /// Random number generator to use for probabilistic primality tests + /// Defines the maximum allowed probability of a false positive. + /// The odds of a composite number being reported as a probable prime are at most 1 in 2^probability + /// Used to inform the function that trial division up to div has already been performed, + /// and so the number is known to have NO divisors <= pretested. + /// Use 0 to inform the function that no trial division has been done. + /// true if the number is probably prime, or false if it is definitely composite. + bool IsProbablePrime(MpirRandom^ random, int probability, mpir_ui pretested); + + /// + /// Determine whether the number is likely a prime, i.e. you can consider it a prime for practical purposes. + /// This function does some trial divisions to speed up the average case, then some probabilistic primality tests. + /// The term "likely" refers to the fact that the number will not have small factors. + /// This function interface is preliminary and may change in the future. + /// + /// Random number generator to use for probabilistic primality tests + /// Used to inform the function that trial division up to div has already been performed, + /// and so the number is known to have NO divisors <= pretested. + /// Use 0 to inform the function that no trial division has been done. + /// true if the number is likely prime, or false if it is definitely composite. + bool IsLikelyPrime(MpirRandom^ random, mpir_ui pretested); + + #pragma endregion }; #pragma endregion