In che modo Lua gestisce i numeri interi e float?


11

Per quanto mi ricordo di aver programmato, mi hanno insegnato a non confrontare i numeri in virgola mobile per l'uguaglianza. Ora, leggendo Programmazione in Lua sul numbertipo di Lua , ho trovato quanto segue:

Il tipo di numero rappresenta numeri reali (a virgola mobile a precisione doppia). Lua non ha un numero intero, in quanto non ne ha bisogno. Esiste un malinteso diffuso sugli errori aritmetici in virgola mobile e alcune persone temono che anche un semplice incremento possa diventare strano con i numeri in virgola mobile. Il fatto è che, quando si utilizza un doppio per rappresentare un numero intero, non si verifica alcun errore di arrotondamento (a meno che il numero non sia maggiore di 100.000.000.000.000). In particolare, un numero Lua può rappresentare qualsiasi numero intero lungo senza problemi di arrotondamento. Inoltre, la maggior parte delle CPU moderne esegue l'aritmetica in virgola mobile alla stessa velocità (o persino più veloce) dell'aritmetica intera.

È vero per tutte le lingue? Fondamentalmente se non andiamo oltre il virgola mobile nei doppi, siamo al sicuro nell'aritmetica dei numeri interi? Oppure, per essere più in linea con il titolo della domanda, c'è qualcosa di speciale che Lua fa con il suo numbertipo, quindi funziona bene sia come numero intero che in virgola mobile?



@JoonasPulakka grazie, è un'aggiunta piuttosto preziosa.
Petr Abdulin,

Risposte:


11

Lua afferma che i numeri in virgola mobile possono rappresentare numeri interi esattamente come i tipi interi, e sono propenso a concordare. Non esiste una rappresentazione imprecisa di una parte numerica frazionaria da affrontare. Se memorizzi un numero intero in un tipo intero o lo memorizzi nella mantissa di un numero in virgola mobile, il risultato è lo stesso: quel numero intero può essere rappresentato esattamente, purché non superi il numero di bit nella mantissa , + 1 bit nell'esponente.

Naturalmente, se provi a memorizzare un numero in virgola mobile (ad es. 12.345) in una rappresentazione in virgola mobile, tutte le scommesse sono disattivate, quindi il tuo programma deve essere chiaro che il numero è davvero un numero intero reale che non trabocca mantissa, al fine di trattarlo come un intero reale (cioè rispetto alla comparazione dell'uguaglianza).

Se hai bisogno di una maggiore precisione dei numeri interi, puoi sempre utilizzare una libreria di precisione arbitraria .

Ulteriori letture
Qual è il valore massimo di un numero in Lua?


Che dire del loro secondo argomento, ovvero che il virgola mobile è più veloce o più veloce dell'aritmetica intera nelle CPU moderne? Mi sembra dubbio, anche quando si usano numeri in virgola mobile per eseguire l'aritmetica dei numeri interi.
Andres F.

2
@AndresF. Non vedo quanto sia più veloce, a meno che tu non stia eliminando un cast utilizzando un solo tipo numerico anziché due.
Robert Harvey,

Concordato. Non ha alcun senso per me. Mi chiedo se sia fuori dal contesto ...
Andres F.

1
I numeri interi sufficientemente grandi non possono essere memorizzati esattamente in un oggetto a virgola mobile. Un 64 bit doubleha circa 51 bit di mantissa; numeri dispari maggiori di circa 2 ** 51 avranno errori di arrotondamento. Un numero intero a 64 bit può memorizzare esattamente valori interi più grandi, poiché non dedica alcun bit a un esponente.
Keith Thompson,

@KeithThompson: ho pensato che fosse implicito nella mia risposta quando ho detto "conservato nella mantissa". Tuttavia, modificherò la risposta per chiarire.
Robert Harvey,

6

I doppi sono immagazzinati come una mantissa e un esponente. Vedi il formato per maggiori informazioni. Fondamentalmente, tutti i numeri sono nella forma: mantissa * 2 esponente . Per qualsiasi numero intero inferiore a 2 52 , l'esponente sarà zero, rendendo la mantissa bit per bit equivalente a un numero intero senza segno a 52 bit. Un bit di segno separato viene utilizzato per indicare numeri negativi.

In effetti, anche alcuni numeri interi maggiori di 2 52 possono essere rappresentati esattamente, purché tutte le cifre oltre il 52 ° siano zeri. Inoltre, alcune frazioni, come 0,5, possono essere rappresentate esattamente. È solo quando la frazione si ripete continuamente (come 1/3) nella base 2, o altrimenti richiede troppi bit oltre il punto radix che si perde precisione.


Non è a causa della ripetizione continua di decimali. È perché molti numeri decimali (base dieci) non possono essere rappresentati esattamente come una potenza di due.
Robert Harvey,

3
Nella base 2, i numeri che non possono essere rappresentati esattamente si ripetono continuamente. Ad esempio, 0,1 decimale diventa 0,0 (0011) in binario, con 0011 che si ripete continuamente.
Karl Bielefeldt,

3
Si, esattamente. Ma non ripetendo nella base 10. Ripetendo nella base 2.
Robert Harvey,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.