Il punto decimale non viene memorizzato in modo esplicito da nessuna parte; questo è un problema di visualizzazione.
La seguente spiegazione è una semplificazione; Sto tralasciando molti dettagli importanti e i miei esempi non intendono rappresentare alcuna piattaforma del mondo reale. Dovrebbe darti un'idea di come i valori in virgola mobile sono rappresentati in memoria e le problematiche ad essi associate, ma vorrai trovare fonti più autorevoli come Ciò che ogni scienziato informatico dovrebbe sapere sull'aritmetica in virgola mobile .
Inizia rappresentando un valore in virgola mobile in una variante della notazione scientifica, usando la base 2 anziché la base 10. Ad esempio, il valore 3.14159 può essere rappresentato come
0.7853975 * 2 2
0.7853975 è il significato , ovvero la mantissa; è la parte del numero che contiene le cifre significative. Questo valore viene moltiplicato per la base 2 elevata alla potenza di 2 per ottenere 3,14159.
I numeri in virgola mobile vengono codificati memorizzando il significato e l'esponente (insieme a un bit di segno).
Un tipico layout a 32 bit è simile al seguente:
3 32222222 22211111111110000000000
1 09876543 21098765432109876543210
+-+--------+-----------------------+
| | | |
+-+--------+-----------------------+
^ ^ ^
| | |
| | +-- significand
| |
| +------------------- exponent
|
+------------------------ sign bit
Come i tipi interi con segno, il bit di ordine superiore indica segno; 0 indica un valore positivo, 1 indica negativo.
I successivi 8 bit vengono utilizzati per l'esponente. Gli esponenti possono essere positivi o negativi, ma invece di riservare un altro bit di segno, sono codificati in modo tale che 10000000 rappresenta 0, quindi 00000000 rappresenta -128 e 11111111 rappresenta 127.
I bit rimanenti vengono utilizzati per il significato. Ogni bit rappresenta una potenza negativa di 2 conteggi da sinistra, quindi:
01101 = 0 * 2 -1 + 1 * 2 -2 + 1 * 2 -3 + 0 * 2 -4 + 1 * 2 -5
= 0,25 + 0,125 + 0,03125
= 0.40625
Alcune piattaforme assumono un bit iniziale "nascosto" nel significato e sempre impostato su 1, quindi i valori nel significato sono sempre compresi tra [0,5, 1). Ciò consente a queste piattaforme di memorizzare valori con una precisione leggermente maggiore (maggiori informazioni su quelle di seguito). Il mio esempio non lo fa.
Quindi il nostro valore di 3.14159 sarebbe rappresentato come qualcosa del genere
0 10000010 11001001000011111100111
^ ^ ^
| | |
| | + --- significato = 0.7853975 ...
| |
| + ------------------- esponente = 2 (130-128)
|
+ ------------------------- segno = 0 (positivo)
valore = -1 (segno) * 2 (esponente) * (significato)
valore = -1 0 * 2 2 * 0.7853975 ...
valore = 3.14159 ...
Ora, qualcosa che noterai se sommi tutti i bit nel significato è che non ammontano a 0,7853975; in realtà escono a 0.78539747. Non ci sono abbastanza bit per memorizzare esattamente il valore ; possiamo solo memorizzare un'approssimazione. Il numero di bit nel significato determina la precisione o quante cifre significative è possibile memorizzare. 23 bit ci danno circa 6 cifre decimali di precisione. I tipi a virgola mobile a 64 bit offrono abbastanza bit nel significato per fornire circa 12-15 cifre di precisione. Ma tieni presente che ci sono valori che non possono essere rappresentati esattamente, non importa comemolti bit che usi. Proprio come valori come 1/3 non possono essere rappresentati in un numero finito di cifre decimali, valori come 1/10 non possono essere rappresentati in un numero finito di bit. Poiché i valori sono approssimativi, anche i calcoli sono approssimativi e si accumulano errori di arrotondamento.
Il numero di bit nell'esponente determina l' intervallo (i valori minimo e massimo che è possibile rappresentare). Ma man mano che ci si sposta verso i valori minimo e massimo, aumenta la dimensione del divario tra valori rappresentabili. Cioè, se non puoi rappresentare esattamente valori compresi tra 0,785397 e 0,785398, allora non puoi rappresentare esattamente né valori compresi tra 7,85397 e 7,85398, o valori compresi tra 78,5397 e 78,5398 o valori tra 785397,0 e 785398,0. Fai attenzione quando moltiplichi numeri molto grandi (in termini di grandezza) per numeri molto piccoli.