Il fatto è che sia un float sia un int sono rappresentati utilizzando 32 bit. Il valore intero utilizza tutti i 32 bit in modo che possa contenere i numeri da -2 a 2 -1. Tuttavia, un float usa 1 bit per il segno (incluso -0.0f) e 8 bit per l'esponente. I mezzi 32 - 9 = 23 bit rimasti per la mantissa. Tuttavia, il float presuppone che se la mantissa e l'esponente non sono zero, allora la mantissa inizia con un 1. Quindi più o meno hai 24 bit per il tuo intero, invece di 32. Tuttavia, poiché può essere spostato, ospita più di 2 numeri interi.
A floating point uses a Sign, an eXponent, and a Mantissa
S X X X X X X X X M M M M M M M M M M M M M M M M M M M M M M M
An integer has a Sign, and a Mantissa
S M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M
Quindi, un numero intero come ad esempio:
1 0 0 1 1 1 1 1 1 0 0 0 0 1 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
si inserisce in un galleggiante, perché può essere spostato:
1 0 0 1 1 1 1 1 1 0 0 0 0 1 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
| | |
| +---------+ +---------+
| | |
v v v
S X X X X X X X X M M M M M M M M M M M M M M M M M M M M M M M
1 1 1 1 1 1 0 0 0 0 1 1 0 0 0 0 1 0 0 0 0 0 0 0
io non ti mostro l'esponente perché il più delle volte commetti un errore nel calcolo, ma dovrebbe essere qualcosa come 5 (o -5?) perché ho spostato di 5 bit (ma devi aggiungere o sottrarre 128 ...). Questo ti mostra chiaramente che se devi spostare di 5 bit, perderai i 5 bit più bassi.
Quindi questo altro intero può essere convertito in un float con una perdita di 2 bit (ovvero quando si converte in un numero intero, gli ultimi due bit (11) sono impostati su zero (00) perché non sono stati salvati in il galleggiante):
1 0 0 1 1 1 1 1 1 0 0 0 0 1 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 1
| | | | | | | |
| +---------+ +---------+ +-+-+-+-+--> all lost
| | |
v v v
S X X X X X X X X M M M M M M M M M M M M M M M M M M M M M M M
1 1 1 1 1 1 0 0 0 0 1 1 0 0 0 0 1 0 0 0 0 0 0 0
Abbastanza semplice roba davvero.
NOTA IMPORTANTE: Sì, il primo 1 nel numero intero è il segno, quindi il primo 1 non viene copiato nella mantissa, si presume che sia 1 quindi non è necessario.
Niente a che fare con il tuo problema specifico, ma se pensi che i float possano essere più veloci del doppio, hai torto: lo scopo dei float è minimizzare i requisiti di archiviazione, che raramente sono un problema per le moderne applicazioni. La scelta predefinita del tipo di dati deve essere doppia, non mobile. –
@Neil: dipende molto dalla CPU. Ci sono molte architetture in cui il float è drammaticamente più veloce del doppio. – jalf
@jalf Possibile, ma nella maggior parte delle situazioni in codice C o C++, i float saranno promossi in doppio comunque. –