8

这个问题的无关理由

我在调用 Lua 时遇到错误format

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

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

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

对于NaN值返回:

值=-1.#IND,类型=数字

我想解决这个问题,但我不知道是谁在生成这个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;

它打印

值=-1.#IND,数字

更新二:以防万一我错过了什么,我的实际代码是:

    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;

错误值输出:

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

更新三

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

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

   ...
end;
4

3 回答 3

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
于 2012-08-24T04:23:30.853 回答
1

Lua 没有 isnan(x)。

您可以将一个添加到您的 Lua 主机或使用该功能创建一个模块。只需几行代码。

如何在 Lua 中测试 -1.#IND 的数字?

好吧,您知道它将 NaN 转换为字符串表示形式'-1.#IND',因此您可以编写:

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

或者,根据平台、编译器、编译器设置等,这将起作用:

function isnan(n) return n ~= n end
于 2012-08-24T04:13:13.457 回答
0

出于序列化目的,这似乎最适合我:

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

这让我:

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

结果是,例如,

{
  foo = 1/0,
  bar = 0/0,
  bla = -1/0,
}
于 2014-04-09T23:37:49.000 回答