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

我在调用Lua的format时遇到了一个错误:

integer overflow attempting to store -1.#IND

变量的type(n)确实是一个number,并且我可以将其格式化为一个字符串(即%s),但它不是一个数字,例如:

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

对于NaN值返回:

value=-1.#IND, type=number

我想解决这个问题,但我不知道是谁产生了这个“NaN”(Lua没有调试器)。

所以我不得不在代码中增加很多asserts,直到我能够确定这个间歇性的NaN值的来源为止。

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

问题

如何在Lua中测试一个数字是否为-1.#IND

更新

我尝试了:

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;

它会打印:

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;

错误的数值输出为:

Is not 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;
点赞
用户501459
用户501459

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-24 04:13:13
用户1442917
用户1442917

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; --只有 NaN 才具有不等于自身的属性
    end;

    --但不是所有的 NaN 都具有不等于自身的属性

    --只有一个数字不能是数字
    if type(x) ~= "number" then
       return false;
    end;

    --在除了英文美国之外的文化中失败,有时在英文美国中也取决于编译器
--  if tostring(x) == "-1.#IND" then

    --更慢,但可以绕过 LUA 中上面的三个 bug
    if tostring(x) == tostring((-1)^0.5) then
        --print("NaN: x = sqrt(-1)");
        return true;
    end;

    --我真的不能再帮你了。
    --你只能忍受这个例外。

    return false;
end
2012-08-24 04:23:30
用户2375540
用户2375540

为了序列化目的,这种方法对我来说似乎是最好的:

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-09 23:37:49