lua-users home
lua-l archive

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

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 to itself, so this isn't what the above is talking about. If you do "y = x",
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.