每日一面 - sqrt (2)約等於 1.414,如何求sqrt (2)小數點後 10 位

1.從 1.414 向下一位開始,二分法查找平方最接近2的數字。效率比較差。

2.使用牛頓迭代法:

  • x初始等於1.414

  • 不斷令x等於x和2/x的平均數,然後求每次x的平方,看與2的差距

  • 這樣比之前的二分法要精簡很多次運算。

這種算法的原理很簡單,我們僅僅是不斷用(x,f(x))的切線來逼近方程x^2-a=0的根。根號a實際上就是x^2-a=0的一個正實根,這個函數的導數是2x。也就是說,函數上任一點(x,f(x))處的切線斜率是2x。那麼,x-f(x)/(2x)就是一個比x更接近的近似值。代入 f(x)=x^2-a得到x-(x^2-a)/(2x),也就是(x+a/x)/2

  1. Chris Lomont 魔法數 + 牛頓迭代,這個偏離了本題條件,因爲本題給了初始數字1.414,但是對於沒有初始猜想的數字,使用魔法數字 0x5f375a86 (源代碼註釋是:what the fxxk???,哈哈哈哈哈,這個數字太匪夷所思了,但是這就是數學的魅力)猜想初始數字,比x等於x2/x的平均數這個初始數字,進行開方平均效率高很多,具體計算過程是:

float InvSqrt(float x)
{
float xhalf = 0.5f*x;
int i = *(int*)&x; // get bits for floating VALUE
i = 0x5f375a86- (i>>1); // gives initial guess y0
x = *(float*)&i; // convert bits BACK to float
x = x*(1.5f-xhalf*x*x); // Newton step, repeating increases accuracy
x = x*(1.5f-xhalf*x*x); // Newton step, repeating increases accuracy
x = x*(1.5f-xhalf*x*x); // Newton step, repeating increases accuracy

return 1/x;
}

這個函數返回的是1/sqrt(x),這個比sqrt(x)更常用於圖像處理,參考這篇論文理解爲啥是 0x5f375a86: http://www.matrix67.com/data/InvSqrt.pdf


本文分享自微信公衆號 - 我的編程喵(MyProCat)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章