为什么lua_tonumber()在处理大整数时与lua_tointeger()有不同的行为?

时间:2013-09-04 08:49:31

标签: c lua

我尝试将字符串从Lua(5.1.5)转换为整数,并检查该数字是否为有效整数(0~99999)。但是,我发现lua_tonumber()在处理大整数时与lua_tointeger()有不同的行为。

int main()
{
    int in;
    double db;

    lua_State* Lua = luaL_newstate();
    luaL_openlibs(Lua);

    lua_pushstring(Lua, "213232127162767162736718238168263816873");
    db = lua_tonumber(Lua, -1);
    in = lua_tointeger(Lua, -1);
    printf("DOUBLE:%f\n", db); // DOUBLE:213232127162767176000119210017101447168.000000
    printf("INT:%d\n", in);    // INT:0
};

如果我使用lua_tointeger(),它将返回0并将通过我的检查。

我检查了两个API描述,但我仍然不知道为什么他们有不同的行为。这些行为是否与机器无关?使用lua_tonumber()是一种更好的方法吗?

我可以使用以下代码检查结果吗? (跨平台)

if (!lua_isnumber(Lua, -1)) { //error }
result = lua_tonumber(Lua, -1);
if (result < 0 || result > 99999) { // error2 }
// pass

1 个答案:

答案 0 :(得分:4)

来自lua_tointeger的手动参考:

  

将给定可接受索引处的Lua值转换为带符号整数类型lua_Integer。 Lua值必须是可转换为数字的数字或字符串(参见§2.2.1);否则,lua_tointeger会返回0

lua_tonumber相同。因此,当您获得0的返回值意味着您传递的是不可兑换的字符串。数字213232127162767162736718238168263816873对于lua_Integer(默认情况下与ptrdiff_t相同)类型来说太大了。

  

这些行为是否与机器无关?使用lua_tonumber()是一种更好的方法吗?

在某种程度上,它与机器有关,因为类型lua_Integer与机器有关。同样,对于任何普通整数类型,数字213232127162767162736718238168263816873都太大了。是否使用lua_tonumber或使用lua_tointeger可以满足您的需求。如果在您的问题中转换小于32位的整数,例如0~9999,则lua_tointeger是您的选择。它在IEEE-754兼容机器中非常快。使用lua_tonumber的缺点是它可能会错误转换非整数值。

参考:A fast method to round a double to a 32-bit int explained