Gerbrand
Gerbrand

Reputation: 5434

Visual studio 2008 unit test keeps failing

I've create a method that calculates the harmonic mean based on a list of doubles. But when I'm running the test it keeps failing even thou the output result are the same.

My harmonic mean method:

public static double GetHarmonicMean(List<double> parameters)
{
    var cumReciprocal = 0.0d;
    var countN = parameters.Count;

    foreach( var param in parameters)
    {
        cumReciprocal += 1.0d/param;
    }

    return 1.0d/(cumReciprocal/countN);
}

My test method:

[TestMethod()]
public void GetHarmonicMeanTest()
{
    var parameters = new List<double> { 1.5d, 2.3d, 2.9d, 1.9d, 5.6d };
    const double expected = 2.32432293165495; 
    var actual = OwnFunctions.GetHarmonicMean(parameters);
    Assert.AreEqual(expected, actual);
}

After running the test the following message is showing:

Assert.AreEqual failed. Expected:<2.32432293165495>. Actual:<2.32432293165495>.

For me that are both the same values.

Can somebody explain this? Or am I doing something wrong?

Upvotes: 4

Views: 158

Answers (3)

Guffa
Guffa

Reputation: 700332

Double values are rounded when they are displayed, so that they display a few digits short of the limit of their capacity (to keep rounding error from showing up). While the values look the same, they actually don't have the exact same value.

You can calculate the value and then display it using the round trip format:

value.ToString("r")

When the textual representation created this way is parsed, it's guaranteed to generate the same double value that created it. You can put that in the code, and it will give you an exact match.

However, generally double values should not be compared for exact equality as you rarely have a situation like this one where you actally want an exact match. Also, testing for an exact match might not be what you actually want in this situation either, as it depends on the implementation remaining exactly the same. If you would use a different algorithm, it would give different rounding errors, giving a slightly different result.

Upvotes: 1

Piotr Justyna
Piotr Justyna

Reputation: 4966

It yould be very difficult to convince GetHarmonicMean method to return exactly 2.32432293165495. Double is much more precise than 14 decimal places. Your result can be for example:

2.32432293165495 - your_result = 0.0000000000000000012345... - this is definitely not zero.

Upvotes: 1

David M
David M

Reputation: 72870

The double overload for Assert.AreEqual takes a "delta" parameter to allow for the imprecision of doubles. You should specify a small value for this parameter.

Upvotes: 7

Related Questions