diff --git a/src/Managed.UnitTests/Managed.UnitTests.csproj b/src/Managed.UnitTests/Managed.UnitTests.csproj
index 7201e5eb..2a773d29 100644
--- a/src/Managed.UnitTests/Managed.UnitTests.csproj
+++ b/src/Managed.UnitTests/Managed.UnitTests.csproj
@@ -67,6 +67,7 @@
+
diff --git a/src/Managed.UnitTests/NumberTheoryTests/GcdRelatedTest.cs b/src/Managed.UnitTests/NumberTheoryTests/GcdRelatedTest.cs
new file mode 100644
index 00000000..b839bb34
--- /dev/null
+++ b/src/Managed.UnitTests/NumberTheoryTests/GcdRelatedTest.cs
@@ -0,0 +1,131 @@
+//
+// 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.NumberTheoryTests
+{
+ using System;
+ using MbUnit.Framework;
+ using NumberTheory;
+
+ [TestFixture]
+ public class GcdRelatedTest
+ {
+ [Test]
+ public void GcdHandlesNormalInputCorrectly()
+ {
+ Assert.AreEqual(0, IntegerTheory.GreatestCommonDivisor(0, 0), "Gcd(0,0)");
+ Assert.AreEqual(6, IntegerTheory.GreatestCommonDivisor(0, 6), "Gcd(0,6)");
+ Assert.AreEqual(1, IntegerTheory.GreatestCommonDivisor(7, 13), "Gcd(7,13)");
+ Assert.AreEqual(7, IntegerTheory.GreatestCommonDivisor(7, 14), "Gcd(7,14)");
+ Assert.AreEqual(1, IntegerTheory.GreatestCommonDivisor(7, 15), "Gcd(7,15)");
+ Assert.AreEqual(3, IntegerTheory.GreatestCommonDivisor(6, 15), "Gcd(6,15)");
+ }
+
+ [Test]
+ public void GcdHandlesNegativeInputCorrectly()
+ {
+ Assert.AreEqual(5, IntegerTheory.GreatestCommonDivisor(-5, 0), "Gcd(-5,0)");
+ Assert.AreEqual(5, IntegerTheory.GreatestCommonDivisor(0, -5), "Gcd(0, -5)");
+ Assert.AreEqual(1, IntegerTheory.GreatestCommonDivisor(-7, 15), "Gcd(-7,15)");
+ Assert.AreEqual(1, IntegerTheory.GreatestCommonDivisor(-7, -15), "Gcd(-7,-15)");
+ }
+
+ [Test]
+ public void GcdSupportsLargeInput()
+ {
+ Assert.AreEqual(Int32.MaxValue, IntegerTheory.GreatestCommonDivisor(0, Int32.MaxValue), "Gcd(0,Int32Max)");
+ Assert.AreEqual(Int64.MaxValue, IntegerTheory.GreatestCommonDivisor(0, Int64.MaxValue), "Gcd(0,Int64Max)");
+ Assert.AreEqual(1, IntegerTheory.GreatestCommonDivisor(Int32.MaxValue, Int64.MaxValue), "Gcd(Int32Max,Int64Max)");
+ Assert.AreEqual(1 << 18, IntegerTheory.GreatestCommonDivisor(1 << 18, 1 << 20), "Gcd(1>>18,1<<20)");
+ }
+
+ [Test]
+ public void ListGcdHandlesNormalInputCorrectly()
+ {
+ Assert.AreEqual(2, IntegerTheory.GreatestCommonDivisor(-10, 6, -8), "Gcd(-10,6,-8)");
+ Assert.AreEqual(1, IntegerTheory.GreatestCommonDivisor(-10, 6, -8, 5, 9, 13), "Gcd(-10,6,-8,5,9,13)");
+ Assert.AreEqual(5, IntegerTheory.GreatestCommonDivisor(-10, 20, 120, 60, -15, 1000), "Gcd(-10,20,120,60,-15,1000)");
+ Assert.AreEqual(3, IntegerTheory.GreatestCommonDivisor(Int64.MaxValue - 1, Int64.MaxValue - 4, Int64.MaxValue - 7), "Gcd(Int64Max-1,Int64Max-4,Int64Max-7)");
+ Assert.AreEqual(123, IntegerTheory.GreatestCommonDivisor(492, -2 * 492, 492 / 4), "Gcd(492, -984, 123)");
+ }
+
+ [Test]
+ public void ListGcdHandlesSpecialInputCorrectly()
+ {
+ Assert.AreEqual(0, IntegerTheory.GreatestCommonDivisor(), "Gcd()");
+ Assert.AreEqual(100, IntegerTheory.GreatestCommonDivisor(-100), "Gcd(-100)");
+ }
+
+ [Test]
+ public void LcmHandlesNormalInputCorrectly()
+ {
+ Assert.AreEqual(10, IntegerTheory.LeastCommonMultiple(10, 10), "Lcm(10,10)");
+
+ Assert.AreEqual(0, IntegerTheory.LeastCommonMultiple(0, 10), "Lcm(0,10)");
+ Assert.AreEqual(0, IntegerTheory.LeastCommonMultiple(10, 0), "Lcm(10,0)");
+
+ Assert.AreEqual(77, IntegerTheory.LeastCommonMultiple(11, 7), "Lcm(11,7)");
+ Assert.AreEqual(33, IntegerTheory.LeastCommonMultiple(11, 33), "Lcm(11,33)");
+ Assert.AreEqual(374, IntegerTheory.LeastCommonMultiple(11, 34), "Lcm(11,34)");
+ }
+
+ [Test]
+ public void LcmHandlesNegativeInputCorrectly()
+ {
+ Assert.AreEqual(352, IntegerTheory.LeastCommonMultiple(11, -32), "Lcm(11,-32)");
+ Assert.AreEqual(352, IntegerTheory.LeastCommonMultiple(-11, 32), "Lcm(-11,32)");
+ Assert.AreEqual(352, IntegerTheory.LeastCommonMultiple(-11, -32), "Lcm(-11,-32)");
+ }
+
+ [Test]
+ public void LcmSupportsLargeInput()
+ {
+ Assert.AreEqual(Int32.MaxValue, IntegerTheory.LeastCommonMultiple(Int32.MaxValue, Int32.MaxValue), "Lcm(Int32Max,Int32Max)");
+ Assert.AreEqual(Int64.MaxValue, IntegerTheory.LeastCommonMultiple(Int64.MaxValue, Int64.MaxValue), "Lcm(Int64Max,Int64Max)");
+ Assert.AreEqual(Int64.MaxValue, IntegerTheory.LeastCommonMultiple(-Int64.MaxValue, -Int64.MaxValue), "Lcm(-Int64Max,-Int64Max)");
+ Assert.AreEqual(Int64.MaxValue, IntegerTheory.LeastCommonMultiple(-Int64.MaxValue, Int64.MaxValue), "Lcm(-Int64Max,Int64Max)");
+ }
+
+ [Test]
+ public void ListLcmHandlesNormalInputCorrectly()
+ {
+ Assert.AreEqual(120, IntegerTheory.LeastCommonMultiple(-10, 6, -8), "Lcm(-10,6,-8)");
+ Assert.AreEqual(4680, IntegerTheory.LeastCommonMultiple(-10, 6, -8, 5, 9, 13), "Lcm(-10,6,-8,5,9,13)");
+ Assert.AreEqual(3000, IntegerTheory.LeastCommonMultiple(-10, 20, 120, 60, -15, 1000), "Lcm(-10,20,120,60,-15,1000)");
+ Assert.AreEqual(984, IntegerTheory.LeastCommonMultiple(492, -2 * 492, 492 / 4), "Lcm(492, -984, 123)");
+ Assert.AreEqual(2016, IntegerTheory.LeastCommonMultiple(32, 42, 36, 18), "Lcm(32,42,36,18)");
+ }
+
+ [Test]
+ public void ListLcmHandlesSpecialInputCorrectly()
+ {
+ Assert.AreEqual(1, IntegerTheory.LeastCommonMultiple(), "Lcm()");
+ Assert.AreEqual(100, IntegerTheory.LeastCommonMultiple(-100), "Lcm(-100)");
+ }
+ }
+}
diff --git a/src/Managed/Managed.csproj b/src/Managed/Managed.csproj
index d392c239..af99fdf5 100644
--- a/src/Managed/Managed.csproj
+++ b/src/Managed/Managed.csproj
@@ -71,6 +71,7 @@
+
diff --git a/src/Managed/NumberTheory/IntegerTheory.Euclid.cs b/src/Managed/NumberTheory/IntegerTheory.Euclid.cs
new file mode 100644
index 00000000..c0f8a191
--- /dev/null
+++ b/src/Managed/NumberTheory/IntegerTheory.Euclid.cs
@@ -0,0 +1,200 @@
+//
+// 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.NumberTheory
+{
+ using System;
+ using System.Collections.Generic;
+
+ ///
+ /// Number theory utility functions for integers.
+ ///
+ public static partial class IntegerTheory
+ {
+ ///
+ /// Returns the greatest common divisor (gcd) of two integers using Euclid's algorithm.
+ ///
+ /// First Integer: a.
+ /// Second Integer: b.
+ /// Greatest common divisor gcd(a,b)
+ public static long GreatestCommonDivisor(long a, long b)
+ {
+ while (b != 0)
+ {
+ long remainder = a % b;
+ a = b;
+ b = remainder;
+ }
+
+ return Math.Abs(a);
+ }
+
+ ///
+ /// Returns the greatest common divisor (gcd) of a set of integers using Euclid's
+ /// algorithm.
+ ///
+ /// List of Integers.
+ /// Greatest common divisor gcd(list of integers)
+ public static long GreatestCommonDivisor(IList integers)
+ {
+ if (null == integers)
+ {
+ throw new ArgumentNullException("integers");
+ }
+
+ if (integers.Count == 0)
+ {
+ return 0;
+ }
+
+ long gcd = Math.Abs(integers[0]);
+
+ for (int i = 1; (i < integers.Count) && (gcd > 1); i++)
+ {
+ gcd = GreatestCommonDivisor(gcd, integers[i]);
+ }
+
+ return gcd;
+ }
+
+ ///
+ /// Returns the greatest common divisor (gcd) of a set of integers using Euclid's algorithm.
+ ///
+ /// List of Integers.
+ /// Greatest common divisor gcd(list of integers)
+ public static long GreatestCommonDivisor(params long[] integers)
+ {
+ return GreatestCommonDivisor((IList)integers);
+ }
+
+ ///
+ /// Computes the extended greatest common divisor, such that a*x + b*y = gcd(a,b).
+ ///
+ /// First Integer: a.
+ /// Second Integer: b.
+ /// Resulting x, such that a*x + b*y = gcd(a,b).
+ /// Resulting y, such that a*x + b*y = gcd(a,b)
+ /// Greatest common divisor gcd(a,b)
+ ///
+ ///
+ /// long x,y,d;
+ /// d = Fn.GreatestCommonDivisor(45,18,out x, out y);
+ /// -> d == 9 && x == 1 && y == -2
+ ///
+ /// The gcd of 45 and 18 is 9: 18 = 2*9, 45 = 5*9. 9 = 1*45 -2*18, therefore x=1 and y=-2.
+ ///
+ public static long ExtendedGreatestCommonDivisor(
+ long a,
+ long b,
+ out long x,
+ out long y)
+ {
+ long mp = 1, np = 0, m = 0, n = 1;
+
+ while (b != 0)
+ {
+ long quot = a / b;
+ long rem = a % b;
+ a = b;
+ b = rem;
+
+ long tmp = m;
+ m = mp - (quot * m);
+ mp = tmp;
+
+ tmp = n;
+ n = np - (quot * n);
+ np = tmp;
+ }
+
+ if (a >= 0)
+ {
+ x = mp;
+ y = np;
+ return a;
+ }
+
+ x = -mp;
+ y = -np;
+ return -a;
+ }
+
+ ///
+ /// Returns the least common multiple (lcm) of two integers using Euclid's algorithm.
+ ///
+ /// First Integer: a.
+ /// Second Integer: b.
+ /// Least common multiple lcm(a,b)
+ public static long LeastCommonMultiple(long a, long b)
+ {
+ if ((a == 0) || (b == 0))
+ {
+ return 0;
+ }
+
+ return Math.Abs((a / GreatestCommonDivisor(a, b)) * b);
+ }
+
+ ///
+ /// Returns the least common multiple (lcm) of a set of integers using Euclid's algorithm.
+ ///
+ /// List of Integers.
+ /// Least common multiple lcm(list of integers)
+ public static long LeastCommonMultiple(IList integers)
+ {
+ if (null == integers)
+ {
+ throw new ArgumentNullException("integers");
+ }
+
+ if (integers.Count == 0)
+ {
+ return 1;
+ }
+
+ long lcm = Math.Abs(integers[0]);
+
+ for (int i = 1; i < integers.Count; i++)
+ {
+ lcm = LeastCommonMultiple(lcm, integers[i]);
+ }
+
+ return lcm;
+ }
+
+ ///
+ /// Returns the least common multiple (lcm) of a set of integers using Euclid's algorithm.
+ ///
+ /// List of Integers.
+ /// Least common multiple lcm(list of integers)
+ public static long LeastCommonMultiple(params long[] integers)
+ {
+ return LeastCommonMultiple((IList)integers);
+ }
+ }
+}
diff --git a/src/Managed/NumberTheory/IntegerTheory.cs b/src/Managed/NumberTheory/IntegerTheory.cs
index b14a5eed..d92a8207 100644
--- a/src/Managed/NumberTheory/IntegerTheory.cs
+++ b/src/Managed/NumberTheory/IntegerTheory.cs
@@ -33,7 +33,7 @@ namespace MathNet.Numerics.NumberTheory
///
/// Number theory utility functions for integers.
///
- public static class IntegerTheory
+ public static partial class IntegerTheory
{
///
/// Find out whether the provided 32 bit integer is an even number.
diff --git a/src/Native.UnitTests/Native.UnitTests.csproj b/src/Native.UnitTests/Native.UnitTests.csproj
index f8e65dde..5a368662 100644
--- a/src/Native.UnitTests/Native.UnitTests.csproj
+++ b/src/Native.UnitTests/Native.UnitTests.csproj
@@ -83,6 +83,9 @@
InterpolationTests\InterpolationTest.cs
+
+ NumberTheoryTests\GcdRelatedTest.cs
+
NumberTheoryTests\IntegerTheoryTest.cs
diff --git a/src/Native/Native.csproj b/src/Native/Native.csproj
index 81515625..ac5f1b07 100644
--- a/src/Native/Native.csproj
+++ b/src/Native/Native.csproj
@@ -122,6 +122,9 @@
NumberTheory\IntegerTheory.cs
+
+ NumberTheory\IntegerTheory.Euclid.cs
+
Precision.cs