¿Cómo probar -1.#IND (indeterminado) en Lua?

Irrelavent justification for the question:

i'm getting an error calling Lua format:

integer overflow attempting to store -1.#IND

La variable type(n) en realidad is a number, and i can format it as a string (i.e. %s), but it's not a number, e.g.:

print(string.format("value=%s, type=%s", n, type(n)));

para NaN value returns:

value=-1.#IND, type=number

i want to fix this, but i have no idea who is generating this NaN (Lua has no debugger).

So i'm left with having to throw a lot of asserts all over the code until i can pin down to the source of this intermittent NaN .

But i can't find any condition that traps it, and Lua doesn't have isnan(x).

Pregunta:

How can i test a number for -1.#IND in Lua?

Noticias:

Lo intenté:

if (n ~= n) then
   print(string.format("NaN: value=%s, type=%s", n, type(n)));
else
   print(string.format("value=%s, type=%s", n, type(n)));
end;

e imprime

value=-1.#IND, number

Actualización dos: Just in case i missed something, my real el código es:

    if (oldValue ~= oldValue) then
        print(string.format("Is NaN: labelNumber=%d, formatString=\"%s\", oldValue=%s (%s)", labelNumber or 0, formatString or "nil", oldValue or "nil", type(oldValue)));
    else
        print(string.format("Is not NaN: labelNumber=%d, formatString=\"%s\", oldValue=%s (%s)", labelNumber or 0, formatString or "nil", oldValue or "nil", type(oldValue)));
    end;

And the faulty value outputs:

Is not NaN: labelNumber=4, formatString="%d", oldValue=-1.#IND (number)

Actualización tres

Still trying to solve this problem, i just noticed the absurdadity of reality:

function isnan(x)
   if type(x) ~= "number" then
       return false; --only a number can not be a number
   end;

   ...
end;

preguntado el 24 de agosto de 12 a las 02:08

what does print(n ~= n) give? -

@Random832 n ~= n devoluciones false cuando n (number) = -1.#IND -

3 Respuestas

n ~= n may work (with the caveats described in Mud's answer), but a more portable one may be:

function isnan(n) return tostring(n) == tostring(0/0) end

Those who are concerned about division by zero (as in Ian's comment; although I haven't seen it in practice) can use an alternative version:

function isnan(n) return tostring(n) == tostring((-1)^.5) end

Función completa:

--local nanString = (tostring((-1) ^ 0.5)); --sqrt(-1) is also NaN. 
--Unfortunately, 
--  tostring((-1)^0.5))       = "-1.#IND"
--  x = tostring((-1)^0.5))   = "0"
--With this bug in LUA we can't use this optimization
local function isnan(x) 
    if (x ~= x) then
        --print(string.format("NaN: %s ~= %s", x, x));
        return true; --only NaNs will have the property of not being equal to themselves
    end;

    --but not all NaN's will have the property of not being equal to themselves

    --only a number can not be a number
    if type(x) ~= "number" then
       return false; 
    end;

    --fails in cultures other than en-US, and sometimes fails in enUS depending on the compiler
--  if tostring(x) == "-1.#IND" then

    --Slower, but works around the three above bugs in LUA
    if tostring(x) == tostring((-1)^0.5) then
        --print("NaN: x = sqrt(-1)");
        return true; 
    end;

    --i really can't help you anymore. 
    --You're just going to have to live with the exception

    return false;
end

Respondido 26 ago 12, 18:08

Cabe señalar que n ~= n does not always work (as @Mud linked to); nor does it work for me. - Ian Boyd

@Ian, right; that's why "tostring(n) == tostring(0/0)" may be a more portable way as I noted. If someone doesn't want the "string" representation to be match, then "type(n) == 'number' and tostring(n) == tostring(0/0)" should do. - Pablo Kulchenko

i also have reports of some people getting "division by zero" errors, rather than "division by zero" simply returning +INF or -INF. - Ian Boyd

@Ian: that's interesting; do you know under what circumstances? I use 0/0 representation in my serializer (github.com/pkulchenko/serpent) and haven't seen any reports about division by zero (although nan numbers seem to be rarely used). - Pablo Kulchenko

i haven't been able to figure out why they'll get a division by zero error on a x = y / z cuando z is zero. My system raises no error. Nonetheless i had check if z == 0 then x = 0 else x = y/z end. - Ian Boyd

Lua doesn't have isnan(x).

You can add one to your Lua host or create a module with that function. Just a few lines of code.

How can i test a number for -1.#IND in Lua?

Well, you know that it's converting NaN in to the string representation '-1.#IND', para que puedas escribir:

function isnan(n) return tostring(n) == '-1.#IND' end

O, depending on the platform, compiler, compiler settings, etc., esto funcionará:

function isnan(n) return n ~= n end

contestado el 23 de mayo de 17 a las 13:05

It's safe to say that for the same reason that n ~= n doesn't always work, that tostring(n) == "-1.#IND" will not always work. Depending on the compiler, platform, or locale, the return of tostring(n) También puede ser NaN (at least in enUS). Some other versions of "Yaya" that you're likely to see are: 非数値, NkN, μη αριθμός, غ ع, ᠲᠤᠭᠠᠠ ᠪᠤᠰᠤ, ཨང་ཀི་མིན་པ།, ꌗꂷꀋꉬ, 不是一個數字, 非数字, NeuN y EdZ. - Ian Boyd

The main objection of the linked question stackoverflow.com/questions/570669/… is a g++ compiler flag called --fast-math and similar optimizations in other compilers, which do not apply to Lua as they do not affect the bytecode. Or at least I don't know how they would. So the only reason for x~=x not working would be if the FPU itself had a non-IEEE conforming floating point implementation. That would be an interesting find though. - dualizado

For serializing purposes, this seems to work best for me:

local function isnan(val)
    if val==1/0 then return "1/0"
    elseif val==-1/0 then return "-1/0"
    elseif val~=val then return "0/0"
    end
end

This lets me:

print(v .. " = " .. isnan(val) or val)

The result is then, for example,

{
  foo = 1/0,
  bar = 0/0,
  bla = -1/0,
}

Respondido 10 Abr '14, 00:04

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.