[Date Prev][Date Next][Thread Prev][Thread Next]
- Subject: Re: checking for Not a Number?
- From: Rici Lake <lua@...>
- Date: Thu, 28 Dec 2006 22:45:06 -0500
On 28-Dec-06, at 8:31 PM, Glenn Maynard wrote:
Putting it another way, if assert(x==y) fails (and neither one is NaN),
then x and y are not the same value, and you're not comparing a value
itself, so this isn't what the above is talking about. If you do "y =
and y is truncated from x, then you're not assigning the same value at
all; you're assigning an approximation, a different value.
Indeed. (Although it rounds, not truncates, at least with the default
settings.) However, I think that particular example is a compiler bug.
I had some trouble reproducing the assert failure. The comparison works
fine on FreeBSD, since FreeBSD sets 53-bit precision by default. The
comparison worked fine using gcc 4.1.1 on Linux, since that version of
gcc seems to be aware that it needs to round the value in the register
before doing the comparison. However, using gcc 3.2.3 on Linux (not my
machine) reproduced the assert failure. Interestingly, when I changed
both instances of 'double' to 'float', gcc 3.2.3 inserted the code to
reduce the precision of the value stored in the register.
It also failed to raise the assertion on gcc 3.2.3 when:
-- I compiled with flags -mfpmath=sse -msse2
-- I compiled with -std=c99 and used 'double_t' instead of 'double'
The C99 standard says:
"Implementations employing wide registers have to take care
to honor appropriate semantics. Values are independent of
whether they are represented in a register or in memory. For
example, an implicit spilling of a register is not permitted
to alter the value. Also, an explicit store and load is
required to round to the precision of the storage type."
Indeed, one could imagine the same bug on a machine whose
instruction set didn't support, say, byte arithmetic; in
such a case, the sum of two char's might be different in
a register than if it were spilled into a storage location.
No self-respecting compiler would generate code which
evidenced that bug -- would it? -- so it's puzzling that
old versions of gcc do so for double precision floating
point. But apparently it's been fixed.