2015-11-06 12 views
8

mi sono imbattuto in questo codice, in cui stanno cercando di convertire da float a intChe tipo di conversione sta facendo questo codice?

int val[5]; 
union { 
    int i; 
    float f; 
} conv; 

... 
val is updated with some value 
... 
case OUT_FORMAT_FLOAT: 
for (i = 0; i < count; i++) { 
    conv.f = val[i]; 
    val[i] = conv.i; 
} 

ma sono solo in grado di capire come questo dovrebbe funzionare. Lo val[i] è assegnato a conv.f e quindi viene utilizzato il valore conv.i per memorizzare il valore in val[i]. conv è un tipo di unione dal momento che stiamo usando f, i non avrà un valore valido giusto?

mi manca qualcosa qui?

+0

consultare http://www.cplusplus.com/doc/tutorial/other_data_types/#unions – hdost

risposta

5

Sta facendo qualcosa chiamato type punning.

La cosa da ricordare qui è che i valori in virgola mobile vengono spesso archiviati in un formato molto diverso rispetto agli interi (più comunemente IEEE floating point format) e l'utilizzo dell'unione consiste nell'ottenere il formato in virgola mobile.

Per essere più precisi, questo è ciò che accade:

  1. L'assegnazione conv.f = val[i]. Converte il numero intero in val[i] in un valore in virgola mobile e lo memorizza in conv.f.
  2. L'assegnazione val[i] = conv.i. Ciò ottiene il modello di bit in virgola mobile grezzo memorizzato nell'unione e lo assegna a val[i].

Questo funziona perché un'unione non è come una struttura con membri separati. In un'unione tutti i membri condividono lo stesso numero di memoria. La modifica di un membro dell'unione modificherà tutti i membri.


Una nota sul perché viene utilizzata un'unione: Questa conversione potrebbe essere fatto in altri modi, ma poi che avrebbe spezzato the strict aliasing rule, tuttavia utilizzando i sindacati per il tipo di giochi di parole è permesso.

+1

Penso che dovresti anche menzionare che praticamente tutti i tipi di punteggiatura sono comportamenti non definiti in base a regole di aliasing rigorose. Afaik, l'unico modo sicuro per ottenere lo schema di bit di un 'float' è usare la funzione' memcpy() '. – cmaster

+0

Quale potrebbe essere lo scopo pratico di questo particolare gioco di parole? Immagino, controllando i bit che rappresentano il float nel numero intero? –

+0

@BlagovestBuyukliev Senza vedere più contesto dall'OP è impossibile per chiunque altro dire. –

0

union consente di memorizzare diversi tipi di dati nella stessa posizione. Lo spazio è assegnato solo per il membro che ha il massimo sizeof(member).

Una volta inizializzato il membro f, è possibile accedere a i da tale posizione.

Problemi correlati