如何在Lua中测试-1.#IND(不确定)?

Ian*_*oyd 7 lua nan ieee-754

这个问题的无关紧要的理由:

我在调用Lua时遇到错误format:

尝试存储-1的整数溢出.#IND

变量type(n)真的一个number,我可以format把它作为一个字符串(即%s),但它不是一个数字,例如:

print(string.format("value=%s, type=%s", n, type(n)));
Run Code Online (Sandbox Code Playgroud)

对于NaN价值回报:

value = -1.#IND,type = number

我想解决这个问题,但我不知道是谁生成这个NaN(Lua没有调试器).

因此,我不得不抛弃大量asserts的代码,直到我可以确定这个间歇性NaN值的来源.

但我找不到任何陷阱的条件,而Lua没有isnan(x).

问题:

我怎样才能-1.#IND在Lua中测试一个数字?

更新:

我试过了:

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;
Run Code Online (Sandbox Code Playgroud)

它打印出来

value = -1.#IND,number

更新二:为了防止我错过了什么,我的实际代码是:

    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;
Run Code Online (Sandbox Code Playgroud)

错误的价值输出:

不是NaN:labelNumber = 4,formatString ="%d",oldValue = -1.#IND(数字)

更新三

仍然试图解决这个问题,我只是注意到现实的荒谬:

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

   ...
end;
Run Code Online (Sandbox Code Playgroud)

Pau*_*nko 4

n ~= n可能有效(带有 Mud 的答案中描述的警告),但更便携的可能是:

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

那些担心被零除的人(如 Ian 的评论;尽管我在实践中没有看到它)可以使用替代版本:

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

功能齐全:

--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
Run Code Online (Sandbox Code Playgroud)