rădăcină pătrată inversă rapidă este un algoritm care estimează , inversul reciproc (sau invers multiplicativ) al rădăcinii pătrate a unui număr în virgulă mobilă pe 32 de biți x în format IEEE 754 în virgulă mobilă. Calculul rădăcinilor pătrate reciproce este necesar în multe aplicații, cum ar fi normalizarea vectorială în jocurile video și este utilizat mai ales în calculele implicate în programarea 3d. În grafica 3D, normalele de suprafață, vectorii cu 3 coordonate de lungime 1 sunt utilizați pentru a exprima iluminarea și reflexia. Au fost o mulțime de normale de suprafață. Și calcularea lor implică normalizarea multor vectori. Normalizarea este adesea doar un termen fantezist pentru divizare. Teorema lui Pitagora calculează distanța dintre puncte, iar împărțirea la distanță ajută la normalizarea vectorilor:
acest algoritm este cel mai bine cunoscut pentru implementarea sa în 1999 în codul sursă al Quake III Arena Game, Un joc video shooter la prima persoană care a folosit intens grafica 3D. În acel moment, era, în general, costisitor din punct de vedere computațional să se calculeze reciprocul unui număr în virgulă mobilă, în special pe scară largă; rădăcina pătrată inversă rapidă a ocolit acest pas.
algoritm:
Pasul 1 : reinterpretează biții intrării în virgulă mobilă ca număr întreg.
i = * ( long * ) &y;
Pasul 2 : este nevoie de valoarea rezultată și face aritmetică întreg pe ea, care produce o aproximare a valorii pe care o căutăm.
i = 0x5f3759df - ( i >> 1 );
Pasul 3 : Rezultatul nu este aproximarea în sine, totuși, este un număr întreg care se întâmplă să fie, dacă reinterpretați biții ca număr în virgulă mobilă, aproximarea. Deci, Codul face inversul conversiei în pasul 1 pentru a reveni la virgulă mobilă:
y = * ( float * ) &i;
Pasul 4: și în cele din urmă rulează o singură iterație a metodei lui Newton pentru a îmbunătăți aproximarea.
y = y * ( threehalfs - ( x2 * y * y ) ); //threehalfs = 1.5F;
algoritmul acceptă un număr în virgulă mobilă pe 32 de biți ca intrare și stochează o valoare înjumătățită pentru o utilizare ulterioară. Apoi, tratând biții reprezentând numărul în virgulă mobilă ca un număr întreg pe 32 de biți, se efectuează o schimbare logică cu un bit și rezultatul este scăzut din numărul magic 0x5F3759DF. Aceasta este prima aproximare a rădăcinii pătrate inverse a intrării. Tratând din nou biții ca număr în virgulă mobilă, rulează o iterație a metodei de aproximare a lui Newton, obținând o aproximare mai precisă.
să presupunem că există un număr în formă exponentă sau notație științifică:
=100 milioane
acum, pentru a găsi rădăcina pătrată obișnuită, am împărți exponentul la 2:
și dacă, doriți să cunoașteți rădăcina pătrată inversă, împărțiți exponentul cu -2 pentru a răsturna semnul:
deci, codul convertește numărul în virgulă mobilă într-un număr întreg. Apoi schimbă biții cu unul, ceea ce înseamnă că biții exponenți sunt împărțiți la 2 (când în cele din urmă transformăm biții înapoi într-un flotor). Și, în sfârșit, pentru a nega exponentul, scădem din numărul magic 0x5f3759df. Acest lucru face câteva lucruri: păstrează mantisa (partea non-exponentă, aka 5 în: 5 · ), se ocupă de exponenți impari, schimbând biți de la exponent în mantisă și tot felul de lucruri funky.
următorul cod este implementarea rapidă a rădăcinii pătrate inverse de la Quake III Arena (comentariul original exact scris în jocul 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;
}
ieșire: