Re: Floating point behavior

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



eool wrote:

> I was reading the C++ FAQ at http://www.parashift.com/c++-faq-lite/ when I
> encountered an interesting curiosity in the "newbie questions" section. The
> FAQ warns against directly comparing floating point numbers and, in section
> 29.18, gives an example of code (see below) that produces behavior that
> seems unnatural to many (most?) programmers. (Below code copied from
> http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.18)
> 
>  #include <cmath>
>  
>  void foo(double x, double y)
>  {
>    if (cos(x) != cos(y)) {
>      std::cout << "Huh?!?\n";  ← you might end up here when x == y!!
>    }
>  }
>  
>  int main()
>  {
>    foo(1.0, 1.0);
>    return 0;
>  } 
> 
> Basically, the reason given in the FAQ is that the result of cos(x)
> (intermediate, higher precision value) will be stored in a register and thus
> truncated. Then the result of cos(y) is directly compared with the truncated
> value located in a register, resulting in this strange (?) behavior. 

The results of Intel's builtin trig functions are long double, not double.
In the example above, the first result may be stored in memory as a double --
therefore truncated -- and compared with a direct result that is long
double.

> Now, my
> question is, why isn't gcc able to tell that it is about to compare two
> floating point numbers, one of which has been truncated, and then similarly
> truncate the second value before the comparison? (In fact, since the return
> type of cos() is double, shouldn't the intermediate value be truncated to
> fit a double in any case?)

I suppose it might be possible, but it would require considerable work.

> Second (this question might be even more naive than the previous one), if
> you are never, ever, supposed to compare floating point numbers using ==; if
> you are always supposed to check the difference of the numbers against an
> epsilon value; then how come the compiler can't automatically do this?

Three reasons:

1.  Anyone with a clue does this anyway.
2.  We compiler writers have no idea what an appropriate value of Epsilon
might be for your application.
3.  The standard doesn't allow us to change code in this way.

> Is it
> because analyzing the source code to track the accumulated floating point
> errors (to appropriately adjust epsilon) might be prohibitively
> difficult/slow? Or are there actually any situations where you'd want to
> compare two floating point numbers directly with each other?

So prohibitively difficult as not to be computable in some cases.

> Thanks for taking the time to answer my "newbie questions" :)

My pleasure.

Andrew.

[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux