Un posto in cui l'ho visto usato è l'attuazione Doom 3/4 IDTech Fast Inverse Square Root.
Per chi non conosce questo algoritmo, essenzialmente richiede il trattamento di un numero in virgola mobile come un intero. Il vecchio Quake (e precedenti) versione del codice fa questo dal seguente:
float y = 2.0f;
// treat the bits of y as an integer
long i = * (long *) &y;
// do some stuff with i
// treat the bits of i as a float
y = * (float *) &i;
original source on GitHub
Questo codice prende l'indirizzo di un numero in virgola mobile y
, l'inserisce in un puntatore a una lunga (cioè, un numero intero a 32 bit in giorni Quake), e lo definisce in i
. Poi fa qualcosa di incredibilmente bizzarro, e il contrario.
Ci sono due svantaggi di farlo in questo modo. Uno è che l'indirizzo-di involuta, fuso, processo dereferenziare forza il valore di y
da leggere dalla memoria, invece che da un registro , e idem al ritorno. Sui computer dell'era di Quake, tuttavia, i registri in virgola mobile e integer erano completamente separati, quindi dovevi praticamente spingere alla memoria e tornare indietro per gestire questa restrizione.
Il secondo è che, almeno in C++, fare questo tipo di casting è profondamente disapprovato, anche quando si fa ciò che equivale al voodoo come fa questa funzione. Sono sicuro che ci sono argomenti più interessanti, però io non sono sicuro di quello che sono :)
Così, in Doom 3, id inclusi i seguenti bit nella loro nuova applicazione (che utilizza un diverso insieme di bit giocherellando, ma un'idea simile):
union _flint {
dword i;
float f;
};
...
union _flint seed;
seed.i = /* look up some tables to get this */;
double r = seed.f; // <- access the bits of seed.i as a floating point number
original source on GitHub
Teoricamente, su una macchina SSE2, questo si può accedere attraverso un unico registro; Non sono sicuro nella pratica se un compilatore lo farebbe. A mio parere, è ancora un po 'un codice più pulito rispetto ai giochi di casting nella precedente versione di Quake.
- ignorando "compilatore sufficientemente avanzati" argomenti
Date un'occhiata a [Tipo-punning] (http://en.wikipedia.org/wiki/Type_punning). – Mysticial
Può essere utile in situazioni in cui è necessario convertire una struct alla sua valori binari (per esempio un char []), senza utilizzare hack puntatore. –
possibile duplicato di [C/C++: quando qualcuno userebbe un sindacato? È fondamentalmente un residuo dei soli giorni C?] (Http: // StackOverflow.it/questions/4788965/cc-when-would-anyone-use-a-union-is-it-fondament-a-remnant-from-the-c-only) –