GeeksforGeeks

Fast inverse vierkantswortel is een algoritme dat {\dfrac{1}{\sqrt{x}}} schat, de wederkerige (of multiplicatieve inverse) van de vierkantswortel van een 32-bit floating-point getal x in IEEE 754 floating-point formaat. Het berekenen van wederkerige vierkantswortels is noodzakelijk in vele toepassingen, zoals Vector normalisatie in videogames en wordt meestal gebruikt in berekeningen die betrokken zijn bij 3D-programmering. In 3D-graphics, oppervlak normalen, 3-coördinaat vectoren van lengte 1 wordt gebruikt, om verlichting en reflectie uit te drukken. Er waren veel oppervlaktenormalen. En het berekenen ervan impliceert het normaliseren van veel vectoren. Normaliseren is vaak gewoon een mooie term voor deling. De stelling van Pythagoras berekent de afstand tussen punten, en delen door afstand helpt vectoren te normaliseren:

dit algoritme is vooral bekend om zijn implementatie in 1999 in de broncode van Quake III Arena Game, een first-person shooter video game die zwaar gebruik gemaakt van 3D-graphics. In die tijd was het over het algemeen rekenkundig duur om de wederkerigheid van een floating-point getal te berekenen, vooral op grote schaal; de snelle inverse vierkantswortel omzeilde deze stap.

algoritme:
Stap 1: het herinterpreteert de bits van de floating-point invoer als een geheel getal.

i = * ( long * ) &y; 

Stap 2: Het neemt de resulterende waarde en doet integer rekenkunde op die een benadering van de waarde die we zoeken produceert.

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

Stap 3: het resultaat is echter niet de benadering zelf, het is een geheel getal dat, als je de bits opnieuw interpreteert als een floating point getal, de benadering is. Dus de code doet het omgekeerde van de conversie in Stap 1 om terug te komen naar zwevend punt:

y = * ( float * ) &i;

Stap 4: en tenslotte draait het een enkele iteratie van Newton ‘ s methode om de benadering te verbeteren.

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

het algoritme accepteert een 32-bits floating-point getal als invoer en slaat een gehalveerde waarde op voor later gebruik. Vervolgens wordt de bits die het floating-point getal vertegenwoordigen behandeld als een 32-bits integer, een logische verschuiving naar rechts met één bit uitgevoerd en wordt het resultaat afgetrokken van het magische getal 0x5F3759DF. Dit is de eerste benadering van de inverse vierkantswortel van de input. De bits opnieuw behandelen als een floating-point getal, het draait een iteratie van Newton ‘ s benadering methode, wat resulteert in een meer nauwkeurige benadering.

stel dat er een getal is in exponentvorm of wetenschappelijke notatie:
{10^8} =100 miljoen
nu, om de reguliere vierkantswortel te vinden, zouden we gewoon de exponent delen door 2:
{\sqrt{{10^8}}}={10^{8/2}}={10^4}=10000
en als je de inverse vierkantswortel wilt weten, deel dan de exponent door -2 om het teken om te draaien:
{\dfrac{1}{\sqrt{10^8}}}={10^{8/-2}}=10^{-4}=\dfrac{1}{10000}

dus de code zet het floating-point getal om in een geheel getal. Het verschuift dan de bits met een, wat betekent dat de exponent bits worden gedeeld door 2 (Wanneer we uiteindelijk de bits terug te zetten in een float). En tot slot, om de exponent te ontkennen, trekken we af van het magische getal 0x5f3759df. Dit doet een paar dingen: het behoudt de mantissa (het niet-exponent deel, aka 5 in: 5 · 10^8), verwerkt Oneven-even exponenten, verschuift stukjes van de exponent naar de mantissa, en allerlei funky dingen.

de volgende code is de snelle inverse vierkantswortel implementatie van Quake III Arena (exact origineel commentaar geschreven in Quake III Arena spel).

#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;
}



Output :



+