diff --git a/Skills/Numerics/Matrix.cs b/Skills/Numerics/Matrix.cs index 926065e..feadcb9 100644 --- a/Skills/Numerics/Matrix.cs +++ b/Skills/Numerics/Matrix.cs @@ -9,6 +9,10 @@ namespace Moserware.Numerics /// internal class Matrix { + // Anything smaller than this will be assumed to be rounding error in terms of equality matching + private const int FractionalDigitsToRoundTo = 10; + private static readonly double ErrorTolerance = Math.Pow(0.1, FractionalDigitsToRoundTo); // e.g. 1/10^10 + protected double[][] _MatrixRowValues; // Note: some properties like Determinant, Inverse, etc are properties instead // of methods to make the syntax look nicer even though this sort of goes against @@ -386,9 +390,7 @@ namespace Moserware.Numerics { return false; } - - const double errorTolerance = 0.0000000000001; - + for (int currentRow = 0; currentRow < a.Rows; currentRow++) { for (int currentColumn = 0; currentColumn < a.Columns; currentColumn++) @@ -397,7 +399,7 @@ namespace Moserware.Numerics Math.Abs(a._MatrixRowValues[currentRow][currentColumn] - b._MatrixRowValues[currentRow][currentColumn]); - if (delta > errorTolerance) + if (delta > ErrorTolerance) { return false; } @@ -426,7 +428,9 @@ namespace Moserware.Numerics for (int currentColumn = 0; currentColumn < Columns; currentColumn++) { - result += multiplier*_MatrixRowValues[currentRow][currentColumn]; + double cellValue = _MatrixRowValues[currentRow][currentColumn]; + double roundedValue = Math.Round(cellValue, FractionalDigitsToRoundTo); + result += multiplier*roundedValue; } } } @@ -443,7 +447,7 @@ namespace Moserware.Numerics int hashCode = BitConverter.ToInt32(finalBytes, 0); return hashCode; } - + public override bool Equals(object obj) { var other = obj as Matrix; diff --git a/Skills/bin/Debug/Moserware.Skills.dll b/Skills/bin/Debug/Moserware.Skills.dll index fe02208..5452efb 100644 Binary files a/Skills/bin/Debug/Moserware.Skills.dll and b/Skills/bin/Debug/Moserware.Skills.dll differ diff --git a/Skills/bin/Debug/Moserware.Skills.pdb b/Skills/bin/Debug/Moserware.Skills.pdb index 940efc4..f014cf6 100644 Binary files a/Skills/bin/Debug/Moserware.Skills.pdb and b/Skills/bin/Debug/Moserware.Skills.pdb differ diff --git a/Skills/bin/Release/Moserware.Skills.dll b/Skills/bin/Release/Moserware.Skills.dll index 5e356be..be69042 100644 Binary files a/Skills/bin/Release/Moserware.Skills.dll and b/Skills/bin/Release/Moserware.Skills.dll differ diff --git a/Skills/bin/Release/Moserware.Skills.pdb b/Skills/bin/Release/Moserware.Skills.pdb index 9d35f80..4158947 100644 Binary files a/Skills/bin/Release/Moserware.Skills.pdb and b/Skills/bin/Release/Moserware.Skills.pdb differ diff --git a/UnitTests/Numerics/MatrixTests.cs b/UnitTests/Numerics/MatrixTests.cs index 1e5ce56..41e4497 100644 --- a/UnitTests/Numerics/MatrixTests.cs +++ b/UnitTests/Numerics/MatrixTests.cs @@ -121,6 +121,16 @@ namespace UnitTests.Numerics Assert.AreEqual(d, f); Assert.AreEqual(d.GetHashCode(), f.GetHashCode()); + // Test rounding (thanks to nsp on GitHub for finding this case) + var g = new SquareMatrix(1, 2.00000000000001, + 3, 4); + + var h = new SquareMatrix(1, 2, + 3, 4); + + Assert.IsTrue(g == h); + Assert.AreEqual(g, h); + Assert.AreEqual(g.GetHashCode(), h.GetHashCode()); } [Test]