关于C#:为什么在处理大整数时lua_tonumber()与lua_tointeger()具有不同的行为?

Why lua_tonumber() has different behavior from lua_tointeger() when dealing with big integer?

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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
"
, db); // DOUBLE:213232127162767176000119210017101447168.000000
    printf("INT:%d
"
, in);    // INT:0
};

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

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

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

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


lua_tointeger的手动参考中:

Converts the Lua value at the given acceptable index to the signed integral type lua_Integer. The Lua value must be a number or a string convertible to a number (see §2.2.1); otherwise, lua_tointeger returns 0

lua_tonumber也是如此。 因此,当您获得0的返回值时,意味着您传递的是不可转换的字符串。 对于lua_Integer(默认与ptrdiff_t相同)类型,数字213232127162767162736718238168263816873太大。

Are these behaviors machine-independent? Is using lua_tonumber() a better way?

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

参考:将双精度数舍入为32位int的快速方法