# How can I properly compare double values for equality in a unit test?

I recently designed a time series module where my time series is essentially a `SortedDictionnary<DateTime, double>`.

Now I would like to create unit tests to make sure that this module is always working and producing the expected result.

A common operation is to compute the performance between the points in the time series.

So what I do is create a time series with, say, {1.0, 2.0, 4.0} (at some dates), and I expect the result to be {100%, 100%}.

The thing is, if I manually create a time series with the values {1.0, 1.0} and I check for equality (by comparing each point), the test would not pass, as there will always be inaccuracies when working with binary representations of real numbers.

Hence, I decided to create the following function:

``````private static bool isCloseEnough(double expected, double actual, double tolerance=0.002)
{
return squaredDifference(expected, actual) < Math.Pow(tolerance,2);
}
``````

Is there another common way of dealing with such a case?

-

I can think of two other ways to deal with this problem:

You can use `Is.InRange`:

``````Assert.That(result, Is.InRange(expected-tolerance, expected+tolerance));
``````

You can use `Math.Round`:

``````Assert.That(Math.Round(result, sigDigits), Is.EqualTo(expected));
``````

I think that both ways are more expressive than a dedicated function, because the reader can see precisely what's going on with your number before it gets compared to the expected value.

-
Just a note that this answer is NUnit specific and showcases the "Constraing-based" assertion model. The classic assertion model would look like: Assert.AreEqual(expected, actual, tolerance); – RichardM Feb 7 '12 at 14:16
@RichardM: Post that as an answer and I will select it accept it. – SRKX Feb 7 '12 at 14:22
The answer by @dasblinkenlight is correct, just adding some detail (since it may not be clear - the classic assertion model is also NUnit). Other test frameworks (not MSTest) likely have their own assert model to deal with floating point values. – RichardM Feb 7 '12 at 14:26
`Assert.That(result, Is.InRange(expected-tolerance, expected+tolerance));` will fail if `tolerance/abs(expected) < 1E-16`. – quant_dev Feb 7 '12 at 15:50
@quant_dev You are absolutely right. Since OP talks about calculating returns as percentages, I assumed that `abs(expected)` would be single to double digits. I also assumed the tolerance in the vicinity of 1E-9. Under these assumptions this admittedly simplistic approach could serve you reasonably well (I use `Is.InRange` in my tests). – dasblinkenlight Feb 7 '12 at 16:05

As RichardM suggested, if you do not use NUnit, the best way seems to be using Assert.AreEqual(double,double,double), where the last one is the precision.

-

It depends what you do with the numbers. If you are testing a method which is supposed to e.g. select an appropriate value from an input set based on some criteria, then you should test for strict equality. If you're doing floating-point calculations, usually you will need to test with a non-zero tolerance. How big the tolerance is depends on the calculations, but with double precision a good starting point is to choose 1E-14 relative tolerance for simple calculations and 1E-8 (tolerance) for more complicated ones. YMMV of course, and you need to add some small absolute tolerance if the expected result is 0.

-

I think this should do it.

``````Assert.That(result, Is.EqualTo(a).Within(double.Epsilon));
``````
-
This is not included in the basic .Net test framework. – SRKX Feb 7 '12 at 15:42
Using absolute precision will fail if `a` is large. – quant_dev Feb 7 '12 at 15:49
@SRXK: Yeah, sorry, I didn't think about MSTest. However, using double.Epsilon as a tolerance should still be effective. – pdr Feb 7 '12 at 15:50