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

时间:2012-08-24 01:40:01

标签: lua nan ieee-754

问题的无关紧要的理由

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

  

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

变量的type(n)确实 number,我可以format将其作为字符串(即%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,数字

更新两次:万一我错过了什么,我的实际代码是:

    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(数字)

更新三

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

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

   ...
end;

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

  

Lua没有isnan(x)。

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

  

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

嗯,你知道它正在将NaN转换为字符串表示'-1.#IND',所以你可以这样写:

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

或者,depending on the platform, compiler, compiler settings, etc.,这将有效:

function isnan(n) return n ~= n end

答案 2 :(得分: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,
}