¿Cómo probar -1.#IND (indeterminado) en Lua?
Frecuentes
Visto 2,953 veces
8
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;
3 Respuestas
4
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
1
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
0
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 lua nan ieee-754 or haz tu propia pregunta.
what does print(n ~= n) give? - Random832
@Random832
n ~= n
devolucionesfalse
cuandon
(number
) =-1.#IND
- Ian Boyd