diff --git a/src/Managed.UnitTests/Managed.UnitTests.csproj b/src/Managed.UnitTests/Managed.UnitTests.csproj
index 369013b0..07468245 100644
--- a/src/Managed.UnitTests/Managed.UnitTests.csproj
+++ b/src/Managed.UnitTests/Managed.UnitTests.csproj
@@ -64,6 +64,7 @@
+
diff --git a/src/Managed.UnitTests/NumberTheoryTests/IntegerTheoryTest.cs b/src/Managed.UnitTests/NumberTheoryTests/IntegerTheoryTest.cs
new file mode 100644
index 00000000..76360979
--- /dev/null
+++ b/src/Managed.UnitTests/NumberTheoryTests/IntegerTheoryTest.cs
@@ -0,0 +1,136 @@
+//
+// 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 NumberTheory;
+ using MbUnit.Framework;
+
+ [TestFixture]
+ public class IntegerTheoryTest
+ {
+ [Test]
+ public void TestEvenOdd32()
+ {
+ Assert.IsTrue(IntegerTheory.IsEven(0), "0 is even");
+ Assert.IsFalse(IntegerTheory.IsOdd(0), "0 is not odd");
+
+ Assert.IsFalse(IntegerTheory.IsEven(1), "1 is not even");
+ Assert.IsTrue(IntegerTheory.IsOdd(1), "1 is odd");
+
+ Assert.IsFalse(IntegerTheory.IsEven(-1), "-1 is not even");
+ Assert.IsTrue(IntegerTheory.IsOdd(-1), "-1 is odd");
+
+ Assert.IsFalse(IntegerTheory.IsEven(Int32.MaxValue), "Int32.Max is not even");
+ Assert.IsTrue(IntegerTheory.IsOdd(Int32.MaxValue), "Int32.Max is odd");
+
+ Assert.IsTrue(IntegerTheory.IsEven(Int32.MinValue), "Int32.Min is even");
+ Assert.IsFalse(IntegerTheory.IsOdd(Int32.MinValue), "Int32.Min is not odd");
+ }
+
+ [Test]
+ public void TestEvenOdd64()
+ {
+ Assert.IsTrue(IntegerTheory.IsEven((long)0), "0 is even");
+ Assert.IsFalse(IntegerTheory.IsOdd((long)0), "0 is not odd");
+
+ Assert.IsFalse(IntegerTheory.IsEven((long)1), "1 is not even");
+ Assert.IsTrue(IntegerTheory.IsOdd((long)1), "1 is odd");
+
+ Assert.IsFalse(IntegerTheory.IsEven((long)-1), "-1 is not even");
+ Assert.IsTrue(IntegerTheory.IsOdd((long)-1), "-1 is odd");
+
+ Assert.IsFalse(IntegerTheory.IsEven(Int64.MaxValue), "Int64.Max is not even");
+ Assert.IsTrue(IntegerTheory.IsOdd(Int64.MaxValue), "Int64.Max is odd");
+
+ Assert.IsTrue(IntegerTheory.IsEven(Int64.MinValue), "Int64.Min is even");
+ Assert.IsFalse(IntegerTheory.IsOdd(Int64.MinValue), "Int64.Min is not odd");
+ }
+
+ [Test]
+ public void TestIsPerfectSquare32()
+ {
+ // Test all known suares
+ int lastRadix = (int)Math.Floor(Math.Sqrt(Int32.MaxValue));
+ for (int i = 0; i <= lastRadix; i++)
+ {
+ Assert.IsTrue(IntegerTheory.IsPerfectSquare(i * i), i + "^2 (+)");
+ }
+
+ // Test 1-offset from all known squares
+ for (int i = 2; i <= lastRadix; i++)
+ {
+ Assert.IsFalse(IntegerTheory.IsPerfectSquare((i * i) - 1), i + "^2-1 (-)");
+ Assert.IsFalse(IntegerTheory.IsPerfectSquare((i * i) + 1), i + "^2+1 (-)");
+ }
+
+ // Selected Cases
+ Assert.IsTrue(IntegerTheory.IsPerfectSquare(100000000), "100000000 (+)");
+ Assert.IsFalse(IntegerTheory.IsPerfectSquare(100000001), "100000001 (-)");
+ Assert.IsFalse(IntegerTheory.IsPerfectSquare(99999999), "99999999 (-)");
+ Assert.IsFalse(IntegerTheory.IsPerfectSquare(-4), "-4 (-)");
+ Assert.IsFalse(IntegerTheory.IsPerfectSquare(Int32.MinValue), "Int32.MinValue (-)");
+ Assert.IsFalse(IntegerTheory.IsPerfectSquare(Int32.MaxValue), "Int32.MaxValue (-)");
+ Assert.IsTrue(IntegerTheory.IsPerfectSquare(1), "1 (+)");
+ Assert.IsTrue(IntegerTheory.IsPerfectSquare(0), "0 (+)");
+ Assert.IsFalse(IntegerTheory.IsPerfectSquare(-1), "-1 (-)");
+ }
+
+ [Test]
+ public void TestIsPerfectSquare64()
+ {
+ // Test all known suares
+ for (int i = 0; i < 32; i++)
+ {
+ long t = ((long)1) << i;
+ Assert.IsTrue(IntegerTheory.IsPerfectSquare(t * t), t + "^2 (+)");
+ }
+
+ // Test 1-offset from all known squares
+ for (int i = 1; i < 32; i++)
+ {
+ long t = ((long)1) << i;
+ Assert.IsFalse(IntegerTheory.IsPerfectSquare((t * t) - 1), t + "^2-1 (-)");
+ Assert.IsFalse(IntegerTheory.IsPerfectSquare((t * t) + 1), t + "^2+1 (-)");
+ }
+
+ // Selected Cases
+ Assert.IsTrue(IntegerTheory.IsPerfectSquare((long)1000000000000000000), "1000000000000000000 (+)");
+ Assert.IsFalse(IntegerTheory.IsPerfectSquare((long)1000000000000000001), "1000000000000000001 (-)");
+ Assert.IsFalse(IntegerTheory.IsPerfectSquare((long)999999999999999999), "999999999999999999 (-)");
+ Assert.IsFalse(IntegerTheory.IsPerfectSquare((long)999999999999999993), "999999999999999993 (-)");
+ Assert.IsFalse(IntegerTheory.IsPerfectSquare((long)-4), "-4 (-)");
+ Assert.IsFalse(IntegerTheory.IsPerfectSquare(Int64.MinValue), "Int32.MinValue (-)");
+ Assert.IsFalse(IntegerTheory.IsPerfectSquare(Int64.MaxValue), "Int32.MaxValue (-)");
+ Assert.IsTrue(IntegerTheory.IsPerfectSquare((long)1), "1 (+)");
+ Assert.IsTrue(IntegerTheory.IsPerfectSquare((long)0), "0 (+)");
+ Assert.IsFalse(IntegerTheory.IsPerfectSquare((long)-1), "-1 (-)");
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Managed/Managed.csproj b/src/Managed/Managed.csproj
index 0a75cf59..1224fdf3 100644
--- a/src/Managed/Managed.csproj
+++ b/src/Managed/Managed.csproj
@@ -65,6 +65,7 @@
+
diff --git a/src/Managed/NumberTheory/IntegerTheory.cs b/src/Managed/NumberTheory/IntegerTheory.cs
new file mode 100644
index 00000000..5fe6926e
--- /dev/null
+++ b/src/Managed/NumberTheory/IntegerTheory.cs
@@ -0,0 +1,126 @@
+//
+// 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;
+
+ ///
+ /// Number Theory for Integers
+ ///
+ public static class IntegerTheory
+ {
+ ///
+ /// Find out whether the provided 32 bit integer is an even number.
+ ///
+ /// True if and only if it is an even number.
+ public static bool IsEven(this int number)
+ {
+ return (number & 0x1) == 0x0;
+ }
+
+ ///
+ /// Find out whether the provided 64 bit integer is an even number.
+ ///
+ /// True if and only if it is an even number.
+ public static bool IsEven(this long number)
+ {
+ return (number & 0x1) == 0x0;
+ }
+
+ ///
+ /// Find out whether the provided 32 bit integer is an odd number.
+ ///
+ /// True if and only if it is an odd number.
+ public static bool IsOdd(this int number)
+ {
+ return (number & 0x1) == 0x1;
+ }
+
+ ///
+ /// Find out whether the provided 64 bit integer is an odd number.
+ ///
+ /// True if and only if it is an odd number.
+ public static bool IsOdd(this long number)
+ {
+ return (number & 0x1) == 0x1;
+ }
+
+ ///
+ /// Find out whether the provided 32 bit integer is a perfect square, i.e. a square of an integer.
+ ///
+ /// True if and only if it is a perfect square.
+ public static bool IsPerfectSquare(int number)
+ {
+ if (number < 0)
+ {
+ return false;
+ }
+
+ int lastHexDigit = number & 0xF;
+ if (lastHexDigit > 9)
+ {
+ return false; // return immediately in 6 cases out of 16.
+ }
+
+ if (lastHexDigit == 0 || lastHexDigit == 1 || lastHexDigit == 4 || lastHexDigit == 9)
+ {
+ int t = (int)Math.Floor(Math.Sqrt(number) + 0.5);
+ return (t * t) == number;
+ }
+
+ return false;
+ }
+
+ ///
+ /// Find out whether the provided 64 bit integer is a perfect square, i.e. a square of an integer.
+ ///
+ /// True if and only if it is a perfect square.
+ public static bool IsPerfectSquare(long number)
+ {
+ if (number < 0)
+ {
+ return false;
+ }
+
+ int lastHexDigit = (int)(number & 0xF);
+ if (lastHexDigit > 9)
+ {
+ return false; // return immediately in 6 cases out of 16.
+ }
+
+ if (lastHexDigit == 0 || lastHexDigit == 1 || lastHexDigit == 4 || lastHexDigit == 9)
+ {
+ long t = (long)Math.Floor(Math.Sqrt(number) + 0.5);
+ return (t * t) == number;
+ }
+
+ return false;
+ }
+ }
+}
diff --git a/src/Native.UnitTests/Native.UnitTests.csproj b/src/Native.UnitTests/Native.UnitTests.csproj
index 9557f2ca..e01748c3 100644
--- a/src/Native.UnitTests/Native.UnitTests.csproj
+++ b/src/Native.UnitTests/Native.UnitTests.csproj
@@ -78,12 +78,15 @@
InterpolationTests\InterpolationTest.cs
+
+ NumberTheoryTests\IntegerTheoryTest.cs
+
PrecisionTest.cs
SpecialFunctionsTest\ErfTests.cs
-
+
diff --git a/src/Native/Native.csproj b/src/Native/Native.csproj
index 5f591f69..9bcfa138 100644
--- a/src/Native/Native.csproj
+++ b/src/Native/Native.csproj
@@ -104,6 +104,9 @@
Interpolation\SplineBoundaryCondition.cs
+
+ NumberTheory\IntegerTheory.cs
+
Precision.cs