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