Permalink
Browse files

Fixed a rounding bug in the Matrix GetHashCode that would cause matri…

…ces that were deemed equal to not have the same hash code
  • Loading branch information...
1 parent 592a82b commit 9bc97fa1c332249ea2eefc775c221ad82fe88756 @moserware committed Apr 26, 2010
View
16 Skills/Numerics/Matrix.cs
@@ -9,6 +9,10 @@ namespace Moserware.Numerics
/// </summary>
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 @@ private double GetCofactor(int rowToRemove, int columnToRemove)
{
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 @@ private double GetCofactor(int rowToRemove, int columnToRemove)
Math.Abs(a._MatrixRowValues[currentRow][currentColumn] -
b._MatrixRowValues[currentRow][currentColumn]);
- if (delta > errorTolerance)
+ if (delta > ErrorTolerance)
{
return false;
}
@@ -426,7 +428,9 @@ public override int GetHashCode()
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 @@ public override int GetHashCode()
int hashCode = BitConverter.ToInt32(finalBytes, 0);
return hashCode;
}
-
+
public override bool Equals(object obj)
{
var other = obj as Matrix;
View
BIN Skills/bin/Debug/Moserware.Skills.dll
Binary file not shown.
View
BIN Skills/bin/Debug/Moserware.Skills.pdb
Binary file not shown.
View
BIN Skills/bin/Release/Moserware.Skills.dll
Binary file not shown.
View
BIN Skills/bin/Release/Moserware.Skills.pdb
Binary file not shown.
View
10 UnitTests/Numerics/MatrixTests.cs
@@ -121,6 +121,16 @@ public void EqualsTest()
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]

0 comments on commit 9bc97fa

Please sign in to comment.