lua-users home
lua-l archive

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



"Luiz Henrique de Figueiredo" <lhf@tecgraf.puc-rio.br> wrote in message 20061220130247.A20506@lua.tecgraf.puc-rio.br">news:20061220130247.A20506@lua.tecgraf.puc-rio.br...
So, can anybody weigh in on this? Is this a bug? If not, why not?

It is not a bug. On IEEE 754 hardware, you can have "numbers" x that do not
satisfy x==x:

% lua51
Lua 5.1.1  Copyright (C) 1994-2006 Lua.org, PUC-Rio
x=math.log(-1)
=x
nan
= x==x
false

What compiler are you using?
--lhf

Directly compairing floating point numbers for equality is *always* a bad idea.

To quote the FSF's "Using the GNU Compiler Collection (GCC)"
(http://www.delorie.com/gnu/docs/gcc/gcc_124.html):
On 68000 and x86 systems, for instance, you can get paradoxical results if you test the precise values of floating point numbers. For example, you can find that a floating point value which is not a NaN is not equal to itself. This results from the fact that the floating point registers hold a few more bits of precision than fit in a double in memory. Compiled code moves values between memory and floating point registers at its convenience, and moving them into memory truncates them.


The important line again:
For example, you can find that a floating point value which is not a NaN is not equal to itself.

Not good.

I'm fairly sure that gcc is follwing the C standard there.
That would mean that the check that Tom Bates quoted could theoretically fail even on a normal floating point number.
It is unlikely that a compiler would actually generate code like that,
but it legally could.

Ideally, the compiler would notice that the code it generated attempts to directly compare a floating point value in the register to a floating point value in memory, and instead copy the value in the register into memory and compare the two memory values. That would fix that problem. Unfortunately, compiler authors do not do that. The C standard does not require them to make that change AFAIK).


Why was the ISO C standard macro "isnan(_real-floating_ x)" not used?
(e.g.
else if (ttisnumber(key) && isnan(nvalue(key)))
       /* ... */
)