GeeksforGeeks

Fast inverse square root to algorytm, który szacuje {\dfrac{1}{\sqrt{x}}}, 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:
{10^8} =100 milion
teraz, aby znaleźć regularny pierwiastek kwadratowy, po prostu podzielilibyśmy wykładnik przez 2:
{\sqrt{{10^8}}}={10^{8/2}}={10^4}=10000
i jeśli chcesz znać odwrotność pierwiastka kwadratowego, podziel wykładnik przez -2, aby odwrócić znak:
 {\dfrac{1}{\sqrt{10^8}}}={10^{8/-2}}=10^{-4}=\dfrac{1}{10000}

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 · 10^8), 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:



+