tags:

views:

114

answers:

2

I am writing unit tests that verify calculations in a database and there is a lot of rounding and truncating and stuff that mean that sometimes figures are slightly off.

When verifying, I'm finding a lot of times when things will pass but say they fail - for instance, the figure will be 1 and I'm getting 0.999999

I mean, I could just round everything into an integer but since I'm using a lot of randomized samples, eventually i'm going to get something like this

10.5 10.4999999999

one is going to round to 10, the other will round to 11.

How should I solve this problem where I need something to be approximately correct?

+8  A: 

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

if (Math.Abs(a - b) < epsilon)
   // Then they are the same

[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.

Mitch Wheat
correct, but this is a C# question, i.e., no abs function and you have Double.Epsilon.
Ed Swangren
@Ed Swangren : pls see addition about size of Double.Epsilon
Mitch Wheat
@Ed Swangren there is too an abs function: http://msdn.microsoft.com/en-us/library/system.math.abs.aspx Math.Abs(...)
Muad'Dib
Yes, as in my example, there is "Math.Abs", there is no "abs" function as one may use in C++.
Ed Swangren
thanks worked perfectly!
RoboShop
Math.Abs(a - b) will *never* be less than Double.Epsilon (unless it is exactly 0), the best you could check for is something *equal to* this value. Double.Epsilon is by definition the smallest positive double value.
Anthony Pegram
Yes, you are correct there.
Ed Swangren
You might want to use an expression such as N * Double.Epsilon
Xavier Poinas
...or just define a larger epsilon like I have above...
Mitch Wheat
+3  A: 

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)
Anthony Pegram
+1 for a correct answer, +1 for suggesting an extension, -1 for not being snobby enough to use a Greek letter. :-)
Steven Sudit
I'd call it `CloseEnoughForGovernmentWork()`, personally
kyoryu