5

There was some code in my project that compared two double values to see if their difference exceeded 0, such as:

if (totValue != 1.0)

Resharper complained about this, suggesting I should use "EPSILON" and added just such a constant to the code (when invited to do so). However, it does not create the constant itself or suggest what value it should be. Is this a good solution:

const double EPSILON = double.Epsilon; // see http://msdn.microsoft.com/en-us/library/system.double.epsilon.aspx
. . .
if (Math.Abs(totValue - 1.0) > EPSILON)
    compValue = Convert.ToString(totValue*Convert.ToDouble(compValue));

?

UPDATE

I changed it to this:

const double EPSILON = 0.001;

...thinking that's probably both large and small enough to work for typical double vals (not scientific stuff, just "I have 2.5 of these," etc.)

B. Clay Shannon-B. Crow Raven
  • 8,547
  • 144
  • 472
  • 862

2 Answers2

3

No, it is not a sensible value for your epsilon. The code you have is no different than a straight equality check.

double.Epsilon is the smallest possible difference that there can be between any two doubles. There is no way for any two doubles to be closer to each other than by being double.Epsilon apart, so the only way for this check to be true is for them to be exactly equal.

As for what epsilon value you should actually use, that simply depends, which is why one isn't automatically generated for you. It all depends on what types of operations you're doing to the data (which affects the possible deviation from the "true value") along with how much precision actually care about in your application (and of course if the precision that you care about is greater than your margin of error, you have a problem). Your epsilon needs to be some precision value greater than (or equal to) the precision you need, while being less than the possible margin of error of all operations performed on either numeric value.

Servy
  • 202,030
  • 26
  • 332
  • 449
  • It's not about 'how much you care about', it is rather 'how much error do you expect'. Setting the epsilon to how much you care about can hide errors. – alzaimar Jun 18 '14 at 20:46
  • @alzaimar The epsilon needs to be *between the two*, as I have said in my answer. You cannot *just* account for one or the other. If there is no space between the two, which is to say that your margin of error is greater than your required precision, then the problem is insolvable, and you'll either need to reduce your margin of error or live with decreased precision. – Servy Jun 18 '14 at 20:49
1

Yes. But even better is to not use floating point. Use decimal instad.

However, if, for some reason, you have to stick to double never compare directly, that means, never rely on e.g. a-b == 0 with (a and b being some double values which are meant to be equal).

Floating point arithmetic is fast, but not precise, and taken that into account, R# is correct.

alzaimar
  • 4,572
  • 1
  • 16
  • 30