Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Floating point equality

It is common knowledge that one has to be careful when comparing floating point values. Usually, instead of using ==, we use some epsilon or ULP based equality testing.

However, I wonder, are there any cases, when using == is perfectly fine?

Look at this simple snippet, which cases are guaranteed to succeed?

void fn(float a, float b) {     float l1 = a/b;     float l2 = a/b;      if (l1==l1) { }        // case a)     if (l1==l2) { }        // case b)     if (l1==a/b) { }       // case c)     if (l1==5.0f/3.0f) { } // case d) }  int main() {     fn(5.0f, 3.0f); } 

Note: I've checked this and this, but they don't cover (all of) my cases.

Note2: It seems that I have to add some plus information, so answers can be useful in practice: I'd like to know:

  • what the C++ standard says
  • what happens, if a C++ implementation follows IEEE-754

This is the only relevant statement I found in the current draft standard:

The value representation of floating-point types is implementation-defined. [ Note: This document imposes no requirements on the accuracy of floating-point operations; see also [support.limits]. — end note ]

So, does this mean, that even "case a)" is implementation defined? I mean, l1==l1 is definitely a floating-point operation. So, if an implementation is "inaccurate", then could l1==l1 be false?


I think this question is not a duplicate of Is floating-point == ever OK?. That question doesn't address any of the cases I'm asking. Same subject, different question. I'd like to have answers specifically to case a)-d), for which I cannot find answers in the duplicated question.

like image 990
geza Avatar asked Jul 02 '18 10:07

geza


People also ask

Does == work for floats?

In the case of floating-point numbers, the relational operator (==) does not produce correct output, this is due to the internal precision errors in rounding up floating-point numbers.

How do you check the equality of a floating point value?

To compare two floating point values, we have to consider the precision in to the comparison. For example, if two numbers are 3.1428 and 3.1415, then they are same up to the precision 0.01, but after that, like 0.001 they are not same.

Why floating point numbers should not be used for equality in expression?

This is because floating point values are not precise, and small rounding errors in the floating point operands may cause unexpected results.

How do you compare floats?

The compare() method of Float Class is a built-in method in Java that compares the two specified float values. The sign of the integer value returned is the same as that of the integer that would be returned by the function call. Parameters: The function accepts two parameters: f1: The first float value to be compared.


2 Answers

However, I wonder, are there any cases, when using == is perfectly fine?

Sure there are. One category of examples are usages that involve no computation, e.g. setters that should only execute on changes:

void setRange(float min, float max) {     if(min == m_fMin && max == m_fMax)         return;      m_fMin = min;     m_fMax = max;      // Do something with min and/or max     emit rangeChanged(min, max); } 

See also Is floating-point == ever OK? and Is floating-point == ever OK?.

like image 188
user2301274 Avatar answered Sep 20 '22 20:09

user2301274


Contrived cases may "work". Practical cases may still fail. One additional issue is that often optimisation will cause small variations in the way the calculation is done so that symbolically the results should be equal but numerically they are different. The example above could, theoretically, fail in such a case. Some compilers offer an option to produce more consistent results at a cost to performance. I would advise "always" avoiding the equality of floating point numbers.

Equality of physical measurements, as well as digitally stored floats, is often meaningless. So if your comparing if floats are equal in your code you are probably doing something wrong. You usually want greater than or less that or within a tolerance. Often code can be rewritten so these types of issues are avoided.

like image 38
William J Bagshaw Avatar answered Sep 21 '22 20:09

William J Bagshaw