-5

I've seen posts like:

What is the most effective way for float and double comparison?

Compare two floats

And many other related posts.

I saw in d3js library, it uses the following comparison:

  return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;

Is it OK to use this in C/C++ to do the comparison of double and float?

Community
  • 1
  • 1
gongzhitaao
  • 6,566
  • 3
  • 36
  • 44
  • 3
    The questions you link attempt to explain *why not*. Was there something mentioned in them that seems unclear? – Drew Dormann Mar 22 '13 at 20:37
  • Sufficient for what? Testing equality or testing equality with an epsilon? The answer is no, either way. – Joseph Mansfield Mar 22 '13 at 20:39
  • @sftrabbit Then that branching you just used could be optimized away to a simple `xor eax, eax` :P –  Mar 22 '13 at 20:40
  • "*UPDATED:...*" Then what you wrote is functionally no different from `a == b`. – Drew Dormann Mar 22 '13 at 20:40
  • Algebraically, (1.0/3.0) * 3.0 = 1.0, but the same cannot be said of doubles or floating point arithmetic in a computer. Just imagine how a PC with limited memory can store an infinitely long rational number 0.333333333333333333333333.... It MUST terminate at some point. Let's say it ends at 0.33. When you multiply 0.33 * 3, you might get 0.99. You might even get 0.98. You could get 1.00. Two of those do NOT "equal" 1.0. – franji1 Mar 22 '13 at 21:20

6 Answers6

7

is the following code sufficient?

No.

If not, why?

Because it's the same as == (at least for non-edge cases, that is.)

  • Internally, the ``<`` combined with ``>`` will be ``==``? – gongzhitaao Mar 22 '13 at 20:46
  • @gongzhitaao define "internally" and "will be" –  Mar 22 '13 at 20:46
  • Why it's the same as ``==``? – gongzhitaao Mar 22 '13 at 20:49
  • 1
    @gongzhitaao Enter the concept of [logic](http://en.wikipedia.org/wiki/Logic). It's pretty useful in real life too. –  Mar 22 '13 at 20:51
  • 2
    @gongzhitaao: Given any 2 real numbers A and B, exactly one of the following is true: One, A is less than B. Two, A is greater than B. Three, A is equal to B. Your test eliminates both the first and second possibilities. That leaves only the third. That they are equal. There are of course differences between floating point values and actual real numbers, but excluding the edge cases, this logic still applies. – Benjamin Lindley Mar 22 '13 at 21:21
  • @H2CO3: Enter the concept of [antisymmetric](http://en.wikipedia.org/wiki/Antisymmetric_relation). Whether `!(aa)` is logically equivalent to `==` is a non-trivial mathematical question. It obviously is true for integers, almost as obvious for reals. But importantly for this question, it is NOT true for IEEE754 floating point math. – MSalters Mar 22 '13 at 22:49
  • @MSalters You seem to have picked me as today's target of your agression. You notice the "at least for non-edge cases" part? –  Mar 22 '13 at 22:53
  • 1
    @H2CO3: I did. But you invoked **logic** to berate gongzhitaao. In fact, he had a very good question. If you apply logic to that question, you just do not end up with your answer. Logic is a mathematical discipline and doesn't ignore edge cases. – MSalters Mar 22 '13 at 23:05
2

This is not sufficient because that will return true if either a or b is NaN

user2152466
  • 59
  • 1
  • 7
1

This is basically about the notion that using "nearly equal" can somehow make up for not knowing enough about floating-point calculations to get reliable results. "Nearly equal" is an advanced technique; it will often bite you because it is not transitive (that is, a "nearly equals" b and b "nearly equals" c does not mean that a "nearly equals" c). If you're a serious programmer, learn the basics of how floating-point works. Nobody's surprised that (1/2)*2) is not 1, but somehow people don't grasp that (1.0/10.0)*10.0 is also not 1 (unless your system has decimal floating point), and for exactly the same reason. That's a failure of education, but having been taught badly doesn't mean you can't learn it. (end of rant)

Pete Becker
  • 74,985
  • 8
  • 76
  • 165
0

The idea of comparing with a tolerance is that two values that are almost exactly the same might want to be considered the same. If you have 2.000000000000 and 2.000000000001, should those be equal, or not? If they should be then your code will fail.

Claudiu
  • 224,032
  • 165
  • 485
  • 680
0

Your mistake is, you read the article which has

   diff = A - B;
   return (diff < EPSILON) && (-diff > EPSILON);

and, you put EPSILON = 0 and turn it into

if (!(a > b) && !(a < b))

You shouldn't suppose EPSILON as 0. Because you should consider a bit error is float/double comparison which we call it EPSILON.

Community
  • 1
  • 1
masoud
  • 55,379
  • 16
  • 141
  • 208
0

You really need to read this document:

https://ece.uwaterloo.ca/~dwharder/NumericalAnalysis/02Numerics/Double/paper.pdf

It is Golberg's paper = whatever every programmer should know about floating point.

jim mcnamara
  • 16,005
  • 2
  • 34
  • 51