Fast inverse square root to algorytm, który szacuje , odwrotność (lub odwrotność mnożnika) pierwiastka kwadratowego 32-bitowej liczby zmiennoprzecinkowej x w formacie zmiennoprzecinkowym IEEE 754. Obliczanie wzajemnych pierwiastków kwadratowych jest niezbędne w wielu zastosowaniach, takich jak normalizacja wektorowa w grach wideo i jest najczęściej stosowane w obliczeniach związanych z programowaniem 3D. W grafice 3D do wyrażania światła i odbicia stosuje się wektory 3-współrzędnych o długości 1. Było dużo normalności powierzchniowych. Ich obliczanie wymaga normalizacji wielu wektorów. Normalizacja jest często tylko wymyślnym określeniem podziału. Twierdzenie Pitagorasa oblicza odległość między punktami, a dzielenie przez odległość pomaga normalizować wektory:
algorytm ten jest najbardziej znany z implementacji w 1999 roku w kodzie źródłowym gry Quake III Arena, gry first-person shooter, która w dużym stopniu wykorzystywała grafikę 3D. W tym czasie obliczanie odwrotności liczby zmiennoprzecinkowej było na ogół kosztowne obliczeniowo, zwłaszcza na dużą skalę; szybki odwrotny pierwiastek kwadratowy ominął ten krok.
algorytm:
Krok 1 : reinterpretuje bity wejścia zmiennoprzecinkowego jako liczbę całkowitą.
i = * ( long * ) &y;
Krok 2: pobiera wynikową wartość i wykonuje na niej arytmetykę całkowitą, która daje przybliżenie wartości, której szukamy.
i = 0x5f3759df - ( i >> 1 );
Krok 3 : wynik nie jest jednak samym przybliżeniem, jest to liczba całkowita, która stanie się, jeśli ponownie zinterpretujesz bity jako liczbę zmiennoprzecinkową, przybliżeniem. Tak więc kod wykonuje odwrotną konwersję w kroku 1, aby wrócić do zmiennoprzecinkowego:
y = * ( float * ) &i;
Krok 4: i na koniec uruchamia pojedynczą iterację metody Newtona, aby poprawić przybliżenie.
y = y * ( threehalfs - ( x2 * y * y ) ); //threehalfs = 1.5F;
algorytm przyjmuje 32-bitową liczbę zmiennoprzecinkową jako wejście i przechowuje połowę wartości do późniejszego wykorzystania. Następnie, traktując bity reprezentujące liczbę zmiennoprzecinkową jako 32-bitową liczbę całkowitą, wykonuje się logiczne przesunięcie w prawo o jeden bit, a wynik odejmuje się od magicznej liczby 0x5f3759df. Jest to pierwsze przybliżenie odwrotnego pierwiastka kwadratowego z danych wejściowych. Traktując bity ponownie jako liczbę zmiennoprzecinkową, wykonuje jedną iterację metody aproksymacji Newtona, uzyskując dokładniejsze aproksymacje.
powiedzmy, że istnieje liczba w postaci wykładnika lub notacji naukowej:
=100 milion
teraz, aby znaleźć regularny pierwiastek kwadratowy, po prostu podzielilibyśmy wykładnik przez 2:
i jeśli chcesz znać odwrotność pierwiastka kwadratowego, podziel wykładnik przez -2, aby odwrócić znak:
kod Konwertuje liczbę zmiennoprzecinkową na liczbę całkowitą. Następnie przesuwa bity o jeden, co oznacza, że bity wykładnika są dzielone przez 2 (Kiedy w końcu zamieniamy bity z powrotem w float). I na koniec, aby zanegować wykładnik, odejmujemy od magicznej liczby 0x5f3759df. To robi kilka rzeczy: zachowuje mantissa (część nie wykładnicza, aka 5 W: 5 · ), obsługuje nieparzyste wykładniki, przesuwa bity z wykładnika do mantissy i wszelkiego rodzaju funky rzeczy.
poniższy kod jest szybką implementacją odwrotnego pierwiastka kwadratowego z Quake III Arena (dokładny oryginalny komentarz napisany w grze Quake III Arena).
#include<bits/stdc++.h>
using
namespace
std;
float
inverse_rsqrt(
float
number )
{
const
float
threehalfs = 1.5F;
float
x2 = number * 0.5F;
float
y = number;
long
i = * (
long
* ) &y;
i = 0x5f3759df - ( i >> 1 );
y = * (
float
* ) &i;
y = y * ( threehalfs - ( x2 * y * y ) );
return
y;
}
int
main(){
int
n = 256;
float
f = inverse_rsqrt(n);
cout << f << endl;
return
0;
}
wyjście: