other/10417: Inconsistent results in floating point comparison.
Craig S. Kaplan
csk@cgl.uwaterloo.ca
Wed Apr 16 14:46:00 GMT 2003
The following reply was made to PR other/10417; it has been noted by GNATS.
From: "Craig S. Kaplan" <csk@cgl.uwaterloo.ca>
To: tprince@computer.org
Cc: gcc-gnats@gcc.gnu.org
Subject: Re: other/10417: Inconsistent results in floating point comparison.
Date: Wed, 16 Apr 2003 10:40:02 -0400 (EDT)
Tim,
Thanks for the insights. If you've got the time, I have some
additional comments below.
> > ---------------------
> > #include <stdio.h>
> > #include <stdlib.h>
> >
> > int main( int argc, char ** argv )
> > {
> > double x = atof( argv[1] );
> > double d = x*x;
> >
> > printf( "%d\n", (x*x<d) );
> > return 0;
> > }
> > -----------------------
> >
> > Ideally, this program should always print 0, since a number shouldn't be
> > strictly less than itself. When compiled without optimization, the program
> > will print 0 or 1 depending on the input (I get 0.3 --> 0, 0.4 --> 1, for
> > instance).
> >
> > Now I understand that floating point numbers are far from ideal, and that
> > this behaviour might not be a bug. Still, I would love to be able to
> > characterize for which numbers the program will print 0 or 1. Any
> > thoughts?
> If you ask the compiler to generate x87 code (the probable default for your
> configuration), it could interpret the expression as
> (long double)x*x < d;
> so the expression would be 1 every time d has been rounded up.
> If you use the command
> gcc -march=pentium4 -mfpmath=sse *.c
> as you might normally do for a P4, I doubt you could get the results you
> mention.
Surprisingly, I _do_ still get the strange behaviour with those
switches.
But I am beginning to understand where the behaviour may be coming
from, based on your comments and the comments of another maintainer
who emailed me (ebotcazou). When d is stored in a variable, some
extra bits of precision that existed in the FPU are discarded. Now,
you seem to suggest that the way the FPU does this is to _round_ d
(rather than just truncating). My simple program seems to generate
random output for different floats, but actually I'm just seeing the
FPU's rounding semantics -- its decision whether to round up or down.
Does that sound believable to you?
Of course, if this is the case, we shouldn't expect -mfpmath=sse
to solve the 'problem' -- we're still rounding x*x to store the
answer in d. The other maintainer suggested that I needed
'-ffloat-store' to guarantee strict IEEE semantics. I tried that
switch, and it seemed to make the behaviour a little more consistent.
It does remove the randomness from the large program I'm working
on, but amazingly it doesn't fix my toy example. Using gcc 3.2.1,
the only way I can make the short program above output 0 consistently
is to compile it -O2. The -ffloat-store, -march=pentium4, and
-mfpmath=sse switches don't seem to do anything. Any thoughts on
why I'm not seeing a difference here?
Thanks again.
--
Craig S. Kaplan ``Evolution drives a steamroller,
School of Computer Science disguised as a stationary bike.''
University of Waterloo http://www.cgl.uwaterloo.ca/~csk/
More information about the Gcc-prs
mailing list