关于invSqrt( )函数
?先解釋下InvSqrt函數(shù)吧!InvSqrt(value)函數(shù)相當(dāng)于1.0/sqrt(value),所以你大概應(yīng)該明白了它是什么意思了吧!由于計(jì)算機(jī)圖形學(xué)程序里經(jīng)常要求一個(gè)面或點(diǎn)的單位法線,就不可避免地要用到1.0/sqrt(length)這樣的式子。你可能會(huì)說(shuō):1.0/sqrt(value)不是挺好的么?這還有什么好拿出來(lái)的?!
? ? ? ?但是!下面的這個(gè)InvSqrt函數(shù)比傳統(tǒng)的1.0/sqrt(value)平均要快4倍,迭代一次就可以得到相應(yīng)的結(jié)果,而且精度很robust。
下面是源代碼:
[cpp]?view plaincopyx = x * (1.5f - xhalf*x*x); // Newton step
? ? ? ? 這一步的由來(lái)。所以這里的關(guān)鍵在于如何選擇一個(gè)好的初始值來(lái)進(jìn)行迭代才能以盡可能少的次數(shù)就達(dá)到足夠的精度呢?代碼中的整形數(shù) i 轉(zhuǎn)換成其機(jī)器碼對(duì)應(yīng)的浮點(diǎn)數(shù)就是一個(gè)很好的初始值,事實(shí)上它非常地接近x的平方根分之一,因此這也是為什么這里只需迭代一次就可以得到很好的結(jié)果的原因。
? ? ? ? 這個(gè)代碼牛逼也正好牛逼在選擇了一個(gè)好的數(shù)據(jù):0x5f375a86-(i>>1),這里的i 是浮點(diǎn)數(shù)x對(duì)應(yīng)的機(jī)器碼轉(zhuǎn)換成的整型數(shù)據(jù)。然后i>>1就是相當(dāng)于i/2,統(tǒng)統(tǒng)左移一位,再用一個(gè)常量來(lái)減i>>2,得到另一個(gè)整型數(shù)據(jù),這個(gè)整形數(shù)據(jù)對(duì)應(yīng)的浮點(diǎn)數(shù)就是一個(gè)滿(mǎn)足要求的初始值了。
? ? ? ? 問(wèn)題的關(guān)鍵在于,你怎么知道要選擇0x5f375a86這么好的一個(gè)數(shù)據(jù)呢?對(duì)此,可以后面的參考論文[InvSqrt.pdf],由于里面的數(shù)學(xué)知識(shí)太多,在這個(gè)頁(yè)面里的排版不太方面,所以就不貼出來(lái)了~~論文中對(duì)于IEEE754浮點(diǎn)數(shù)據(jù)的格式進(jìn)行了分析,并將浮點(diǎn)部分與指數(shù)部分分開(kāi)討論,對(duì)指數(shù)的奇偶作了一番探討,最后將R-(i>>1)中的R范圍給大致地確定出來(lái),并分析不同取值的結(jié)果。大家如果不喜歡看這些頭疼的數(shù)學(xué),了解一下這個(gè)代碼到底是怎么回事就行了,沒(méi)有必要深究。
? ??
參考論文:http://www.matrix67.com/data/InvSqrt.pdf
總結(jié)
以上是生活随笔為你收集整理的关于invSqrt( )函数的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 四元数姿态解算及多传感器融合详细解析
- 下一篇: 十六进制数转换成float类型数据数据的