Почему 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:%fn", db); // DOUBLE:213232127162767176000119210017101447168.000000
    printf("INT:%dn", in);    // INT:0
};

Если я использую lua_tointeger (), он возвращает 0 и передаст мою проверку.

Я проверяю оба описания API, но я все еще не знаю, почему они имеют разное поведение. Являются ли эти модели поведения машинно-независимыми? Использует lua_tonumber () a лучший способ?

могу ли я использовать следующий код для проверки результата? (кросс-платформенный)

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

1 ответов


из руководства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 слишком большой для любого нормального типа integer. Ли используя lua_tonumber или через lua_tointeger до вашей потребности. Если преобразование целого числа меньше 32-разрядного, например, 0~99999 в вашем вопросе, lua_tointeger - Это ваш выбор. Это очень быстро в совместимой машине IEEE-754. Недостаток использования lua_tonumber заключается в том, что он может неправильно преобразования нецелого значения.

ссылки: быстрый метод округления двойника до 32-битного int объяснил