How to safely check if two floating point expressions are different?

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

 



Hi,

I have some code where I need to know whether two floating point
expressions are different (and, if they are, whether their difference
is positive).  Unsafe optimizations of some sort seem to be made (I'm
compiling at "-O2 -funroll-loops", though I can demonstrate a simple
test case that fails with no optimizations).  I found a solution, but
it assumes the compiler isn't smart enough to aggressively inline
functions.

My question is: How can I write my code so that it functions correctly
even with potentially future versions of gcc that can aggressively
inline code in its optimizer?

For reference, I have attached a simple test case at the end of this
email that exhibits the problem I'm facing.  (It appears that either
some extended precision arithmetic is used (perhaps using floating
point registers?), or that some optimizations which assume floating
point arithmetic is associative are being done.  But doing that
results in lying to me about whether i+a and i are different floating
point expressions).

Thanks,
Elijah

double
is_greater(double a, double b)
{
  return a > b;
}

int
main()
{
  int i = 10;
  double a = 4e-16;

  printf ("i + a > i         :  %s\n",
          (i+a > i)          ? "TRUE" : "FALSE");
  printf ("(i + a)-i > 0     :  %s\n",
          ((i+a)-i > 0)      ? "TRUE" : "FALSE");
  printf ("is_greater(i+a,i) :  %s\n",
          is_greater(i+a,i)  ? "TRUE" : "FALSE");

  return 0;
}

/* Output from this program when compiled under gcc (WITH OR WITHOUT
 * optimizations!!!!):
 *
 *   i + a > i         :  TRUE
 *   (i + a)-i > 0     :  TRUE
 *   is_greater(i+a,i) :  FALSE
 *
 * However, if I declare is_greater to be inline and use an
 * optimization level where the inline hint is acknowledged and used,
 * then I get TRUE printed out every time.  Which I don't want, since
 * i+a and i, as doubles, are exactly equal.
 */

[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