Jednym z miejsc, w którym widziałem używane, jest implementacja Doom 3/idTech 4 Fast Inverse Square Root.
Dla tych, którzy nie znają tego algorytmu, zasadniczo wymaga traktowania liczby zmiennoprzecinkowej jako liczby całkowitej. Stary Quake (i wcześniej) wersja kodu robi to brzmienie:
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
Kod ten bierze adresu zmiennoprzecinkowej liczby y
, rzuca go do wskaźnika do długi (tj. 32-bitowa liczba całkowita w dniach Quake) i zrzeczenie się jej na i
. A potem robi niesamowicie dziwaczne, dręczące rzeczy, i na odwrót.
Są dwie wady robienia tego w ten sposób. Jednym z nich jest to, że skomplikowany proces adresowania, odlewania, dereferencji wymusza odczytanie z pamięci wartości y
, a nie z rejestru , a także w drodze powrotnej. Jednak na komputerach z Quake'em rejestry zmiennoprzecinkowe i liczby całkowite były całkowicie oddzielne, więc musieliście wcisnąć do pamięci iz powrotem, aby poradzić sobie z tym ograniczeniem.
Po drugie, przynajmniej w C++, wykonywanie takich rzutów jest głęboko nachmurzone, nawet jeśli robi to, co równa się voodoo, takie jak ta funkcja. Jestem pewien, że są bardziej przekonujące argumenty, ale nie jestem pewien, co to jest :)
Tak więc, w Doom 3, id zawierał następujący bit w ich nowej implementacji (która używa innego zestawu bitowego twiddling, ale podobny pomysł):
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
Teoretycznie, na maszynie SSE2, to można uzyskać za pośrednictwem pojedynczego rejestru; Nie jestem pewien w praktyce, czy jakikolwiek kompilator by to zrobił. To wciąż nieco czystszy kod w mojej opinii niż gry castingowe we wcześniejszej wersji gry Quake.
- pomijając "wystarczająco zaawansowane kompilatora" argumenty
Spójrz na [Type-paronomazja] (http://en.wikipedia.org/wiki/Type_punning). – Mysticial
Może być użyteczny w sytuacjach, w których trzeba przekonwertować strukturę na jej wartości binarne (np. Char []), bez użycia narzędzi hakerskich. –
możliwy duplikat [C/C++: Kiedy ktoś użyłby związku? Czy to w zasadzie pozostałość po dniach C?] (Http: // stackoverflow.com/questions/4788965/cc-when-would-anyone-use-a-union-is-it-basic-a-remnant-from-the-c-only) –