2013-09-04 6 views
6

Ho provato a convertire una stringa da Lua (5.1.5) in un numero intero e verificare se il numero è un numero intero valido (0 ~ 99999). Tuttavia, ho trovato che lua_tonumber() ha un comportamento diverso da lua_tointeger() quando si ha a che fare con un intero grande.Perché lua_tonumber() ha un comportamento diverso da lua_tointeger() quando si ha a che fare con un numero intero grande?

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

Se uso lua_tointeger(), restituisce 0 e passerà il mio controllo.

Controllo entrambe le descrizioni API, ma non so ancora perché hanno comportamenti diversi. Questi comportamenti sono indipendenti dalla macchina? Sta usando lua_tonumber() in un modo migliore?

Posso utilizzare il codice seguente per verificare il risultato? (Cross-platform)

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

Interi sono 2 o 4 byte, 'double' è di 8 byte. – hjpotter92

risposta

4

Dalla riferimento manuale di lua_tointeger:

Converte il valore Lua al determinato indice accettabile per il tipo integrale firmata lua_Integer. Il valore Lua deve essere un numero o una stringa convertibile in un numero (vedere §2.2.1); in caso contrario, restituisce lua_tointeger0

Lo stesso è con lua_tonumber. Quindi, quando ottieni il valore di ritorno di 0 significa che stai passando una stringa non convertibile. Il numero 213232127162767162736718238168263816873 è troppo grande per un tipo lua_Integer (lo stesso di ptrdiff_t per impostazione predefinita).

Questi comportamenti sono indipendenti dalla macchina? Sta usando lua_tonumber() in un modo migliore?

In un modo, dipende dalla macchina, poiché il tipo lua_Integer dipende dalla macchina. Anche in questo caso, il numero 213232127162767162736718238168263816873 è troppo grande per qualsiasi tipo di intero normale. Se si utilizza lua_tonumber o utilizzando lua_tointeger è su vostra necessità. Se si converte un numero intero inferiore a 32 bit, ad esempio 0 ~ 99999 nella domanda, lua_tointeger è la vostra scelta. È molto veloce in una macchina compatibile IEEE-754. Lo svantaggio dell'uso di lua_tonumber è che potrebbe erroneamente convertire valori non interi.

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

+0

Grazie, questa informazione è utile. – Yalieee