How do I find if two variables are approximately equals?

Define a tolerance value (aka an 'epsilon' or 'delta'), for instance, 0.00001, and then use to compare the difference like so:

if (Math.Abs(a - b) < delta)
{
   // Values are within specified tolerance of each other....
}

You could use Double.Epsilon but you would have to use a multiplying factor.

Better still, write an extension method to do the same. We have something like Assert.AreSimiliar(a,b) in our unit tests.

Microsoft's Assert.AreEqual() method has an overload that takes a delta: public static void AreEqual(double expected, double actual, double delta)

NUnit also provides an overload to their Assert.AreEqual() method that allows for a delta to be provided.


You could provide a function that includes a parameter for an acceptable difference between two values. For example

// close is good for horseshoes, hand grenades, nuclear weapons, and doubles
static bool CloseEnoughForMe(double value1, double value2, double acceptableDifference)
{
    return Math.Abs(value1 - value2) <= acceptableDifference; 
}

And then call it

double value1 = 24.5;
double value2 = 24.4999;

bool equalValues = CloseEnoughForMe(value1, value2, 0.001);

If you wanted to be slightly professional about it, you could call the function ApproximatelyEquals or something along those lines.

static bool ApproximatelyEquals(this double value1, double value2, double acceptableDifference)

I haven't checked in which MS Test version were added but in v10.0.0.0 Assert.AreEqual methods have overloads what accept a delta parameter and do approximate comparison.

I.e. https://msdn.microsoft.com/en-us/library/ms243458(v=vs.140).aspx

//
// Summary:
//     Verifies that two specified doubles are equal, or within the specified accuracy
//     of each other. The assertion fails if they are not within the specified accuracy
//     of each other.
//
// Parameters:
//   expected:
//     The first double to compare. This is the double the unit test expects.
//
//   actual:
//     The second double to compare. This is the double the unit test produced.
//
//   delta:
//     The required accuracy. The assertion will fail only if expected is different
//     from actual by more than delta.
//
// Exceptions:
//   Microsoft.VisualStudio.TestTools.UnitTesting.AssertFailedException:
//     expected is different from actual by more than delta.
public static void AreEqual(double expected, double actual, double delta);

One way to compare floating point numbers is to compare how many floating point representations that separate them. This solution is indifferent to the size of the numbers and thus you don't have to worry about the size of "epsilon" mentioned in other answers.

A description of the algorithm can be found here (the AlmostEqual2sComplement function in the end) and here is my C# version of it.

UPDATE: The provided link is outdated. The new version which includes some improvements and bugfixes is here

public static class DoubleComparerExtensions
{
    public static bool AlmostEquals(this double left, double right, long representationTolerance)
    {
        long leftAsBits = left.ToBits2Complement();
        long rightAsBits = right.ToBits2Complement();
        long floatingPointRepresentationsDiff = Math.Abs(leftAsBits - rightAsBits);
        return (floatingPointRepresentationsDiff <= representationTolerance);
    }

    private static unsafe long ToBits2Complement(this double value)
    {
        double* valueAsDoublePtr = &value;
        long* valueAsLongPtr = (long*)valueAsDoublePtr;
        long valueAsLong = *valueAsLongPtr;
        return valueAsLong < 0
            ? (long)(0x8000000000000000 - (ulong)valueAsLong)
            : valueAsLong;
    }
}

If you'd like to compare floats, change all double to float, all long to int and 0x8000000000000000 to 0x80000000.

With the representationTolerance parameter you can specify how big an error is tolerated. A higher value means a larger error is accepted. I normally use the value 10 as default.