0

Visualizzatore mobile IEEE-754

Scopri esattamente come un numero decimale viene memorizzato come float IEEE-754 (bit di segno, bit dell'esponente e bit della mantissa) e perché numeri come 0,1 non vengono memorizzati esattamente.

Buy Me a Coffee at ko-fi.com
Elaborazione... 0%
Normalizzazione
Calcolo della distorsione dell'esponente
Bit di mantissa in espansione
Fatto

Risultato

Ogni numero in virgola mobile memorizzato da un computer (un numero JavaScript, un float C, un float Python) è codificato allo stesso modo in IEEE 754: un bit di segno, un blocco di bit di esponente e un blocco di bit di mantissa (frazione). La precisione singola (32 bit) utilizza 1 bit di segno, 8 bit di esponente e 23 bit di mantissa; la doppia precisione (64 bit), il formato alla base del tipo di numero predefinito di quasi tutte le lingue, utilizza 1 bit di segno, 11 bit di esponente e 52 bit di mantissa. Questo strumento prende qualsiasi numero decimale digitato, lo codifica in entrambe le larghezze utilizzando il codificatore float DataView/ArrayBuffer del browser (lo stesso macchinario su cui viene effettivamente eseguito il codice) e colora ogni bit in base alla regione a cui appartiene.

La codifica stessa segue tre passaggi e questo strumento li esamina tutti invece di mostrare solo i bit finali. Innanzitutto, la normalizzazione: il numero viene riscritto come 1.mantissa × 2^esponente, con esattamente una cifra diversa da zero prima del punto binario (i numeri troppo piccoli per questo ottengono invece il trattamento subnormale, senza 1 implicito iniziale). In secondo luogo, la distorsione dell'esponente: poiché il campo dell'esponente deve memorizzare sia gli esponenti positivi che quelli negativi come un numero senza segno, viene aggiunta una distorsione fissa (127 per precisione singola, 1023 per doppia) prima che il campo venga scritto in binario. In terzo luogo, la mantissa frazionaria viene espansa poco a poco con il classico metodo "moltiplica per due, prendi la parte intera come bit successivo, mantieni il resto" - ripetuto fino a quando il campo della mantissa è pieno, a quel punto i bit rimanenti decidono se il risultato verrà arrotondato per eccesso o per difetto (arrotonda da metà a pari, impostazione predefinita IEEE-754).

Questo è esattamente il motivo per cui un numero ordinario come 0,1 non viene memorizzato esattamente. In binario, 0,1 è una frazione ripetuta (0,0001100110011..., per sempre), quindi nessuna mantissa finita può contenerla con precisione: deve essere arrotondata da qualche parte. Codifica 0.1 come float a 32 bit e rileggi i bit e non ottieni 0.1: ottieni esattamente 0.100000001490116119384765625. La doppia precisione ha 29 bit di mantissa in più con cui lavorare, quindi il suo errore di arrotondamento è molto più piccolo, ma non è nemmeno zero: 0,1 poiché un doppio a 64 bit è esattamente 0,100000000000005625. Questo strumento calcola l'esatto valore memorizzato con l'aritmetica dei numeri interi grandi (senza scorciatoie in virgola mobile) in modo che il divario tra ciò che hai digitato e ciò che l'hardware effettivamente conserva non venga mai nascosto o approssimato.

I valori speciali ottengono modelli di bit esatti e riservati anziché una codifica normale: zero e zero negativo hanno bit dell'esponente e della mantissa tutti zero (differisce solo il bit del segno), ±Infinity ha bit dell'esponente tutto uno con una mantissa tutto zero e NaN ha bit dell'esponente tutto uno con almeno un bit della mantissa impostato. Tutto qui viene eseguito localmente nel tuo browser - niente di ciò che scrivi viene caricato da nessuna parte - il che lo rende un posto sicuro per creare una vera intuizione per i bug in virgola mobile: perché `0.1 + 0.2 !== 0.3` in quasi tutti i linguaggi di programmazione, perché le texture float32 nel codice grafico perdono precisione che float64 non farebbe e perché il codice finanziario dovrebbe generalmente evitare del tutto il punto mobile binario.