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

我试图将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
点赞
用户1009479
用户1009479

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〜99999,lua_tointeger 是你的选择。在符合IEEE-754的机器上,它非常快。使用 lua_tonumber 的缺点是它可能错误地转换非整数的值。

参考资料:解释将 double 快速舍入为 32 位 int 的方法

2013-09-04 08:59:18