GeeksforGeeks

Rychle inverzní odmocnina je algoritmus, který odhaduje, {\dfrac{1}{\sqrt{x}}}, reciproční (nebo multiplikativní inverzní) na odmocnině z 32-bit floating-point číslo x v IEEE 754 floating-point formátu. Výpočet vzájemných odmocnin je nezbytný v mnoha aplikacích, jako je normalizace vektorů ve videohrách a většinou se používá při výpočtech zapojených do 3D programování. V 3D grafice se používají povrchové normály, 3-souřadnicové vektory délky 1, které vyjadřují osvětlení a odraz. Bylo tam hodně povrchových normálů. A jejich výpočet zahrnuje normalizaci mnoha vektorů. Normalizace je často jen efektní termín pro dělení. Pythagorova věta počítá vzdálenosti mezi body, a vydělením vzdálenosti pomáhá normalizovat vektory:

Tento algoritmus je nejlépe známý pro jeho provádění v roce 1999 ve zdrojovém kódu Quake III Arena Hry, first-person střílečka video hra, která dělal těžké použití 3D grafiky. Toho času, bylo obecně výpočetně nákladné vypočítat reciproční číslo s plovoucí desetinnou čárkou, zejména ve velkém měřítku; rychlá inverzní druhá odmocnina tento krok obešla.

algoritmus:
Krok 1: reinterpretuje bity vstupu s plovoucí desetinnou čárkou jako celé číslo.

i = * ( long * ) &y; 

Krok 2 : vezme výslednou hodnotu a provede na ní celočíselnou aritmetiku, která vytvoří aproximaci hodnoty, kterou hledáme.

i = 0x5f3759df - ( i >> 1 );

Krok 3 : výsledek není sbližování právních sám, i když to je číslo, které se stane, pokud si reinterpretovat bitů jako číslo s plovoucí čárkou, sbližování. Takže kód provede obrácenou konverzi v kroku 1, aby se vrátil zpět na plovoucí desetinnou čárku:

y = * ( float * ) &i;

Krok 4: a nakonec spustí jednu iteraci Newtonovy metody ke zlepšení aproximace.

y = y * ( threehalfs - ( x2 * y * y ) ); //threehalfs = 1.5F;

algoritmus přijímá jako vstup 32bitové číslo s plovoucí desetinnou čárkou a ukládá poloviční hodnotu pro pozdější použití. Pak, léčbě bitů reprezentuje desetinné číslo jako 32-bitové celé číslo, logický posun vpravo o jeden bit je provedena a výsledek odečte od magické číslo 0x5F3759DF. Toto je první aproximace inverzní druhé odmocniny vstupu. Léčení bitů zase jako číslo s plovoucí desetinnou čárkou, to běží jedna iterace newtonovy metody aproximace, čímž se získá přesnější aproximace.

řekněme, že číslo v exponentu formě nebo vědecké notaci:
{10^8} =100 milionů
Nyní, najít pravidelné odmocnina, jen bychom je rozdělit tím, že exponent 2:
{\sqrt{{10^8}}}={10^{8/2}}={10^4}=10000
A pokud, chcete vědět, inverzní odmocnina, rozdělit tím, že exponent -2 otočit ceduli:
{\dfrac{1}{\sqrt{10^8}}}={10^{8/-2}}=10^{-4}=\dfrac{1}{10000}

Takže, kód převede desetinné číslo na celé číslo. To pak posune bity o jeden, což znamená, že exponent bity jsou děleny 2 (Když jsme nakonec zase bity zpět do plováku). A konečně, abychom negovali exponent, odečteme od magického čísla 0x5f3759df. To znamená několik věcí: zachovává mantisa (non-exponent část, aka 5 v: 5 · 10^8), zpracovává liché sudé exponenty, řazení bitů z exponent do mantisy, a všechny druhy funky věci.

následující kód je rychlá inverzní druhá odmocnina implementace z Quake III Arena (přesný původní komentář napsaný ve hře 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;
}



Výstup :



+