最原始的版本不是求開方,而是求開方倒數,也即。為啥這樣,原因有二。首先,開方倒數在實際應用中比開方更常見,例如在遊戲中經常會執行向量的歸一化操作,而該操作就需要用到開方倒數。另乙個原因就是開方倒數的牛頓迭代沒有除法操作,因而會比先前的牛頓迭代(
由這個公式我們就很清楚地明白**y=y*(threehalfs-(x2*y*y))的含義,這其實就是執行了單次牛頓迭代。為啥只執行了單次迭代就完事了呢?因為單次迭代的精度已經達到相當高的程度。
為什麼單次迭代就可以達到精度要求呢?根據之前的分析我們可以知道,最根本的原因就是選擇的初值非常接近精確解。而估計初始解的關鍵就是下面這句**:
i = 0x5f3759df - ( i >> 1 );
正是由於這句**,特別是其中的「magic number」使演算法的初始解非常接近精確解。具體的原理是位址強**首先將float型別的數直接進行位址轉換轉成int型(**中long在32位機器上等價於int),然後對int型的值進行乙個神奇的操作,最後再進行位址轉換轉成float型別就是很精確的初始解。
float型浮點數和對應的int型整數之間的關係給出乙個公式
有了這個公式我們就可以推導初始解的由來了。要求
這個公式就是神奇操作的數學表示,公式中只有
演算法的最終目的是要對浮點數開平方,該演算法效能非常高,而且精度也很高,三次迭代精度就和系統函式一樣,但是速度只有系統函式sqrtf的十分之一不到,相當了得。
#include "stdio.h"
#include "conio.h"
float q_rsqrt( float number )
int main()
舉例:x=2^e(1+f)=5.125=2^2(1+0.28125)
ix=el+f=l(e+b+f)=2^23(2+127+0.28125)=2^23*10000001.01001=0(符號)10000001(階碼)
01001000000000000000000(尾數)(8388608*129.28125=1084489728)
ix表示浮點數的整數表示,e=e+b表示ieee階碼值,l=
12582912*(127-0.0450466)-1/2*1084489728=1597463007-542244864=1055218143=01111101 11001010101100111011111
y=*(float*)&i=2^(-2)*1.791805148124694824≈ 0.447951287
y1 =y(1.5-2.5625y^2)≈ 0.441593890
卡馬克卷軸演算法
念 這裡使用簡化的概念,精確的定義請參考計算機圖形學中二維觀察流程。世界座標系 用於標註整個遊戲世界的座標系。攝像機 攝像機攝到的區域才能顯示在螢幕上,攝像機在本文中表現為乙個視窗,視窗內的世界才能顯示到螢幕上進而被看到。移動攝像機到不同的位置就可以觀察不同位置的情形。卡馬克卷軸演算法 如圖所示,當...
卡馬克卷軸演算法
概念 這裡使用簡化的概念,精確的定義請參考計算機圖形學中二維觀察流程。世界座標系 用於標註整個遊戲世界的座標系。卡馬克卷軸演算法 img 如圖所示,當前內容是 1230。當攝像機向右下移動時,其內容應該變為0564,這樣就形成了卷軸的效果。由原位置變化為新位置的具體做法是 使用兩個緩衝區 當前緩衝區...
神奇卡馬克
卡馬克主要成就基於他在3d方面的研究,idsoftware開發的著名遊戲有德軍總部3d wolfenstein 3d 毀滅戰士 doom 和雷神之鎚 quake 等等。這些遊戲和它們的後續版本都取得了巨大的成功。卡馬克創造的遊戲引擎還用來製作其他的第一人稱射擊遊戲,比如半條命 half life 和...