Почему 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 объяснил