Il punto decimale non è memorizzato esplicitamente da nessuna parte; questo è un problema di visualizzazione.
La seguente spiegazione è una semplificazione; Tralascio un lotto di dettagli importanti e i miei esempi non intendono rappresentare alcuna piattaforma reale. Dovrebbe darti un'idea di come i valori in virgola mobile sono rappresentati in memoria e dei problemi ad essi associati, ma vorrai trovare fonti più autorevoli come Ciò che ogni scienziato informatico dovrebbe sapere sull'aritmetica virgola mobile .
Inizia rappresentando un valore a virgola mobile in una variante della notazione scientifica, utilizzando la base 2 invece della base 10. Ad esempio, il valore 3.14159 può essere rappresentato come
0.7853975 * 22
0,7853975 è il significante , a.k.a. la mantissa; è la parte del numero contenente le cifre significative. Questo valore viene moltiplicato per la base 2 aumentata alla potenza di 2 per ottenere 3,14159.
I numeri in virgola mobile sono codificati memorizzando il significato e l'esponente (insieme a un bit di segno).
Un tipico layout a 32 bit ha un aspetto simile al seguente:
3 32222222 22211111111110000000000
1 09876543 21098765432109876543210
+-+--------+-----------------------+
| | | |
+-+--------+-----------------------+
^ ^ ^
| | |
| | +-- significand
| |
| +------------------- exponent
|
+------------------------ sign bit
Come i tipi di interi con segno, il bit di ordine superiore indica il segno; 0 indica un valore positivo, 1 indica negativo.
I successivi 8 bit sono usati per l'esponente. Gli esponenti possono essere positivi o negativi, ma invece di riservare un altro 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 e. Ogni bit rappresenta una potenza negativa di 2 conteggio 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 che è sempre impostato su 1, quindi i valori nel significato e sono sempre compresi tra [0.5, 1). Ciò consente a queste piattaforme di archiviare valori con una precisione leggermente maggiore (maggiori informazioni in seguito). Il mio esempio non lo fa.
Quindi il nostro valore di 3,14159 sarebbe rappresentato come qualcosa di simile
0 10000010 11001001000011111100111
^ ^ ^
| | |
| | +--- significand = 0.7853975...
| |
| +------------------- exponent = 2 (130 - 128)
|
+------------------------- sign = 0 (positive)
value= -1(sign) * 2(exponent) * (significand)
value= -10 * 22 * 0.7853975...
value= 3.14159...
Ora, qualcosa che noterai se sommi tutti i bit nel significato e che non sono pari a 0.7853975; in realtà escono allo 0,78539747. Non ci sono abbastanza bit per memorizzare il valore esattamente ; possiamo solo memorizzare un'approssimazione. Il numero di bit nel significato e determina precisione o il numero di cifre significative che è possibile memorizzare. 23 bit ci forniscono circa 6 cifre decimali di precisione. I tipi a virgola mobile a 64 bit offrono abbastanza bit nel significato e forniscono circa 12-15 cifre di precisione. Ma tieni presente che ci sono valori che non possono essere rappresentati esattamente non importa come molti 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 con essi sono approssimativi e gli errori di arrotondamento si accumulano.
Il numero di bit nell'esponente determina l'intervallo (i valori minimo e massimo che puoi rappresentare). Ma mentre ci si sposta verso i valori minimi e massimi, aumenta la dimensione della distanza tra i valori rappresentabili. In altre parole, se non è possibile rappresentare esattamente i valori compresi tra 0,785397 e 0,785398, non è possibile rappresentare esattamente i valori compresi tra 7.85397 e 7.85398 o tra 78.5397 e 78.5398 o tra 785397.0 e 785398.0. Fai attenzione quando moltiplichi numeri molto grandi (in termini di grandezza) con numeri molto piccoli.