GeeksforGeeks

nopea käänteisneliöjuuri on algoritmi, joka arvioi {\dfrac{1}{\sqrt{x}}}, joka on 32-bittisen liukulukuluvun x käänteisarvo (tai multiplikatiivinen käänteisarvo) IEEE 754 liukulukumuodossa. Vastavuoroisten neliöjuurten laskenta on välttämätöntä monissa sovelluksissa, kuten vektorien normalisoinnissa videopeleissä, ja sitä käytetään enimmäkseen 3D-ohjelmointiin liittyvissä laskelmissa. 3D-grafiikassa käytetään pintanormaaleja, 3-koordinaattivektoreita, joiden pituus on 1, ilmaisemaan valaistusta ja heijastusta. Pintanormaaleja oli paljon. Ja niiden laskemiseen kuuluu monien vektorien normalisointi. Normalisointi on usein vain hieno termi jaolle. Pythagoraan lause laskee pisteiden välisen etäisyyden, ja jakamalla etäisyys auttaa normalisoimaan vektoreita:

algoritmi tunnetaan parhaiten vuonna 1999 toteutetusta Quake III Arena-pelin lähdekoodista, ensimmäisen persoonan ammuntapelistä, jossa käytettiin runsaasti 3D-grafiikkaa. Tuohon aikaan oli yleensä laskennallisesti kallista laskea liukulukuluvun käänteisluku, erityisesti suuressa mittakaavassa; nopea Käänteinen neliöjuuri ohitti tämän vaiheen.

algoritmi :
Vaihe 1 : se tulkitsee liukulukutulon bitit uudelleen kokonaislukuna.

i = * ( long * ) &y; 

Vaihe 2: Se ottaa tuloksena olevan arvon ja tekee sille kokonaislukuaritmetiikan, joka tuottaa likiarvon etsimästämme arvosta.

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

Vaihe 3: tuloksena ei kuitenkaan ole itse approksimaatio, vaan kokonaisluku, joka sattuu olemaan, jos tulkitsee bitit uudelleen liukulukuna, approksimaatio. Joten koodi ei Käänteinen muuntaminen vaiheessa 1 saada takaisin liukuluku:

y = * ( float * ) &i;

Vaihe 4: ja lopuksi se suorittaa yhden iteraation Newtonin menetelmä parantaa lähentämisestä.

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

algoritmi hyväksyy syötteeksi 32-bittisen liukulukuluvun ja tallentaa puolitetun arvon myöhempää käyttöä varten. Tämän jälkeen käsitellään liukulukulukua esittäviä bittejä 32-bittisenä kokonaislukuna, suoritetaan looginen siirto yhden bitin verran oikealle ja tulos vähennetään taikaluvusta 0x5F3759DF. Tämä on tulon käänteisen neliöjuuren ensimmäinen approksimaatio. Käsitellessään bitit jälleen liukulukuna se suorittaa yhden iteraation Newtonin likiarvomenetelmästä, jolloin saadaan tarkempi likiarvo.

sanotaan, että on olemassa luku eksponenttimuodossa tai tieteellisessä notaatiossa:
{10^8} =100 million
Now, to find the regular square root, we ’ d just jaamme exponent by 2:
{\sqrt{{10^8}}}={10^{8/2}}={10^4}=10000
ja jos haluat tietää käänteisen neliöjuuren, Jaa eksponentti -2: lla kääntääksesi merkin:
 {\dfrac{1}{\sqrt{10^8}}}={10^{8/-2}}=10^{-4}=\dfrac{1}{10000}

eli koodi muuntaa liukulukuluvun kokonaisluvuksi. Se sitten siirtää bitit yhdellä, mikä tarkoittaa eksponenttibitit jaetaan 2: lla (kun lopulta muutamme bitit takaisin floatiksi). Ja lopuksi, mitätöidäksemme eksponentin, vähennämme taikaluvusta 0x5f3759df. Tämä tekee muutamia asioita: se säilyttää mantissa (ei-eksponentti osa, aka 5 in: 5 · 10^8), käsittelee parittomia eksponentteja, siirtäen bittejä eksponentista mantissaan, ja kaikenlaista outoa tavaraa.

seuraava koodi on Quake III Arenan nopea Käänteinen neliöjuuritoteutus (tarkka alkuperäinen kommentti kirjoitettu Quake III Arena-peliin).

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



Lähtö:



+