I tipi a virgola mobile (come Single e Double) sono rappresentati in memoria da un segno, una mantissa e un esponente. Pensalo come una notazione scientifica:
Sign*Mantissa*Base^Exponent
Loro - come ci si può aspettare - usano la base 2. Ci sono altre modifiche che consentono di rappresentare l'infinito e il NaN, e l'esponente è sfalsato (tornerà a quello) e una scorciatoia per la mantissa (tornerà anche a quello) . Cerca lo standard IEEE 754 che copre la sua rappresentazione e le operazioni per maggiori dettagli.
Per i nostri scopi possiamo immaginarlo come un numero binario "mantissa" e un "esponente" che ti dice dove mettere il separatore decimale.
Nel caso di Single, abbiamo 1 bit per il suo segno, 8 per l'esponente e 23 per la mantissa.
Ora, il fatto è che memorizzeremo la mantissa dalla cifra più significativa. Ricorda che tutti gli zeri a sinistra non sono rilevanti. E dato che stiamo lavorando in binario, sappiamo che la cifra più significativa è 1 ※. Bene, poiché lo sappiamo, non è necessario memorizzarlo. Grazie a quella scorciatoia, l'intervallo effettivo della mantissa è di 24 bit.
※: A meno che il numero che stiamo memorizzando sia zero. Per questo avremo tutti i bit impostati su zero. Tuttavia, se proviamo a interpretare ciò sotto la descrizione che ho dato, avresti un 2 ^ 24 (l'implicito 1) moltiplicato per 1 (2 alla potenza dell'esponente 0). Quindi, per risolverlo, lo zero esponente è un valore speciale. Ci sono anche valori speciali per memorizzare l'infinito e NaN nell'esponente.
Secondo l'offset dell'esponente - oltre a evitare i valori speciali - il suo offset consente di posizionare il punto decimale prima dell'inizio della mantissa o dopo la sua fine, senza la necessità di avere un segno per l'esponente.
Ciò significa che per numeri grandi, il tipo a virgola mobile metterà il punto decimale oltre la fine della mantissa.
Ricorda che la mantissa è un numero di 24 bit. Non rappresenterà mai un numero di 25 bit ... non ha quel bit in più. Pertanto, il singolo non può distinguere tra 2 ^ 24 e 2 ^ 24 + 1 (questi sono i primi numeri di 25 bit e differiscono sull'ultimo bit, che non è rappresentato nel singolo).
Pertanto, per i numeri interi l'intervallo del singolo è compreso tra -2 ^ 24 e 2 ^ 24. E provare ad aggiungere da 1 a 2 ^ 24 si tradurrà in 2 ^ 24 (perché per quanto riguarda il tipo, 2 ^ 24 e 2 ^ 24 + 1 hanno lo stesso valore). Provalo online . Questo è il motivo per cui si verifica una perdita di informazioni durante la conversione da intero a singolo. Ed è anche per questo che un loop che utilizza un singolo o un doppio potrebbe effettivamente essere un loop infinito senza che te ne accorga.