GeeksforGeeks

snabb invers kvadratrot är en algoritm som uppskattar  {\dfrac{1}{\sqrt{x}}}, den ömsesidiga (eller multiplikativa inversen) av kvadratroten av ett 32-bitars flytpunktsnummer x i IEEE 754 flytpunktsformat. Beräkning av ömsesidiga kvadratrötter är nödvändig i många applikationer, såsom vektornormalisering i videospel och används mest i beräkningar som är involverade i 3D-programmering. I 3D-grafik används ytnormaler, 3-koordinatvektorer med Längd 1 för att uttrycka belysning och reflektion. Det fanns många ytnormaler. Att beräkna dem innebär att man normaliserar många vektorer. Normalisering är ofta bara en fin term för division. Pythagoras sats beräknar avståndet mellan punkter, och delning med avstånd hjälper till att normalisera vektorer:

denna algoritm är mest känd för sin implementering 1999 i källkoden för Quake III Arena Game, ett första person shooter-videospel som använde 3D-grafik kraftigt. Vid den tiden var det i allmänhet beräkningsmässigt dyrt att beräkna det ömsesidiga av ett flytpunktsnummer, särskilt i stor skala; den snabba inversa kvadratroten kringgick detta steg.

algoritm:
Steg 1 : det tolkar bitarna i flytpunktsinmatningen som ett heltal.

i = * ( long * ) &y; 

steg 2 : Det tar det resulterande värdet och gör heltal aritmetik på det som ger en approximation av värdet vi letar efter.

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

steg 3 : resultatet är inte själva approximationen, men det är ett heltal som råkar vara, om du tolkar bitarna som ett flyttal, approximationen. Så koden gör det omvända av konverteringen i steg 1 för att komma tillbaka till flyttal:

y = * ( float * ) &i;

steg 4: och slutligen körs en enda iteration av Newtons metod för att förbättra approximationen.

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

algoritmen accepterar ett 32-bitars flytpunktsnummer som ingång och lagrar ett halverat värde för senare användning. Sedan behandlas bitarna som representerar flytpunktsnumret som ett 32-bitars heltal, en logisk förskjutning höger med en bit utförs och resultatet subtraheras från det magiska numret 0x5f3759df. Detta är den första approximationen av den inversa kvadratroten av ingången. Behandla bitarna igen som ett flytpunktsnummer, det kör en iteration av Newtons approximationsmetod, vilket ger en mer exakt approximation.

låt oss säga att det finns ett tal i exponentform eller vetenskaplig notation:
{10^8} =100 miljoner
nu, för att hitta den vanliga kvadratroten, skulle vi bara dela exponenten med 2:
{\sqrt{{10^8}}}={10^{8/2}}={10^4}=10000
och om du vill veta den inversa kvadratroten, dela exponenten med -2 för att vända tecknet:
 {\dfrac{1} {\sqrt{10^8}}}={10^{8/-2}}=10^{-4}=\dfrac{1}{10000}

så omvandlar koden flytpunktsnumret till ett heltal. Det skiftar sedan bitarna med en, vilket innebär att exponentbitarna delas med 2 (när vi så småningom vänder bitarna tillbaka till en flottör). Och slutligen, för att negera exponenten, subtraherar vi från det magiska numret 0x5f3759df. Detta gör några saker: det bevarar mantissa (den icke-exponentdelen, aka 5 in: 5 · 10^8), hanterar Udda Jämn exponenter, skiftande bitar från exponenten till mantissa och alla slags funky saker.

följande kod är den snabba inverse kvadratrot genomförandet från Quake III Arena (exakt original kommentar skriven i 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;
}



utgång:



+