2013-09-04 12 views
6

Próbowałem konwertować ciąg znaków z Lua (5.1.5) na liczbę całkowitą i sprawdzić, czy liczba jest poprawną liczbą całkowitą (0 ~ 99999). Jednakże, stwierdziłem, że lua_tonumber() ma inne zachowanie niż lua_tointeger(), gdy mamy do czynienia z dużą liczbą całkowitą.Dlaczego lua_tonumber() ma inne zachowanie od lua_tointeger(), gdy mamy do czynienia z dużą liczbą całkowitą?

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 
}; 

Jeśli użyję lua_tointeger(), to zwraca 0 i przejdzie moje sprawdzanie.

Sprawdzam oba opisy API, ale nadal nie wiem, dlaczego mają różne zachowania. Czy te zachowania są niezależne od maszyny? Czy używasz lua_tonumber() w lepszy sposób?

Czy mogę użyć następującego kodu, aby sprawdzić wynik? (I platform)

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

liczby całkowite 2 lub 4 bajtów, 'double' ma 8 bajtów. – hjpotter92

Odpowiedz

4

od instrukcji odniesienia lua_tointeger:

przekształca wartość Lua w danym dopuszczalny indeks podpisanej integralną typu lua_Integer. Wartość Lua musi być liczbą lub łańcuchem zamiennym na liczbę (patrz § 2.2.1); w przeciwnym razie, lua_tointeger powraca 0

tak samo jest z lua_tonumber. Więc kiedy otrzymasz wartość zwracaną 0 oznacza, że ​​przekazujesz ciąg, który nie jest zamienny. Numer 213232127162767162736718238168263816873 jest zbyt duży dla typu lua_Integer (taki sam jak ptrdiff_t domyślnie).

Czy te zachowania są niezależne od maszyny? Czy używasz lua_tonumber() w lepszy sposób?

W pewnym sensie jest to zależne od komputera, ponieważ typ lua_Integer zależy od urządzenia. Ponownie, numer 213232127162767162736718238168263816873 jest zbyt duży dla dowolnego normalnego typu całkowitego. Niezależnie od tego, czy używasz lua_tonumber czy używasz lua_tointeger, to wszystko zależy od Twoich potrzeb. W przypadku konwersji liczby całkowitej mniejszej niż 32-bitowa, na przykład 0-99999 w pytaniu, należy wybrać opcję lua_tointeger. Jest bardzo szybki w urządzeniu kompatybilnym z IEEE-754. Wadą korzystania z lua_tonumber jest to, że może on błędnie przekonwertować wartości niecałkowite.

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

+0

Dzięki, ta informacja jest przydatna. – Yalieee

Powiązane problemy