計算平方根的演算法

2021-07-05 07:03:52 字數 1787 閱讀 2974

總結一下一些常用的計算平方根的方法

1.  牛頓法

具體的做法如下: 

計算公式如下: 

具體的計算程式如下: 

double sqrt_(

double x)         

return g; }

2. 利用級數進行逼近

微積分中的泰勒級數如下:

這樣,有了這個公式我們可以得到求平方根公式的展開式:

這樣我們可以進行在一定精度內的逼近。

但是這兒存在乙個問題,就是這個公式的收斂問題。它是存在收斂區間的。  

所以可以得到最後的**:

double tsqrt(

double x)

//計算[0,2)範圍內數的平方根

return sum; }

double sqrt2(

double x)

//大於2的數要轉化為[0,2)區間上去

return tsqrt(x)*correction; }

3. 平方根倒數速演算法

這是牛頓迭代法的應用。 

維基百科介紹

牛頓迭代法是一種求方程的近似根的方法。首先要估計乙個與方程的根比較靠近的數值,然後根據公式推算下乙個更加近似的數值,不斷重複直到可以獲得滿意的精度。其公式如下:

函式:y=f(x)

其一階導數為:y'=f'(x)

則方程:f(x)=0 的第n+1個近似根為

x[n+1] = x[n] - f(x[n]) / f'(x[n])

牛頓迭代法最關鍵的地方在於估計第乙個近似根。如果該近似根與真根足夠靠近的話,那麼只需要少數幾次迭代,就可以得到滿意的解。 現在回過頭來看看如何利用牛頓法來解決我們的問題。求平方根的倒數,實際就是求方程1/(x^2)-a=0的解。將該方程按牛頓迭代法的公式展開為:

x[n+1]=1/2*x[n]*(3-a*x[n]*x[n])

這個方法的乙個關鍵地方還在於起始值的選取。

具體**如下: 

float squarerootfloat(

float number) 

該方法又叫卡馬克反轉。其中的0x5f3759df的來歷比較複雜,在維基百科中也有介紹。最後的參考中也有介紹。

最後三種方法的測試**如下: 

#include 

#include 

#include 

#include 

#include 

#define timeb timeb

#define abs(x) ((x)>0?(x):-(x))

#define eps 0.0000000001

time_t time_test(

double x,

double *y,

double(*func)(

double))

double sqrt1(

double x)

return g;

}double tsqrt(

double x)

return sum;

}double sqrt2(

double x)

return tsqrt(x)*correction;

}double sqrt3(

double xi) 

int main()

return

0; }

結果如下: 

第一列是隨機數,第二列是庫函式sqrt, <>中的是時間,y1是方法1,y2是方法2,y3是方法3

看來這三種方法時間都挺快,都小於毫秒 

參考:

快速計算平方根

在3d圖形程式設計中,經常要求平方根或平方根的倒數,例如 求向量的長度或將向量歸一化。c數學函式庫中的sqrt具有理想的精度,但對於3d遊戲程式來說速度太慢。我們希望能夠在保證足夠的精度的同時,進一步提高速度。carmack在quake3中使用了下面的演算法,它第一次在公眾場合出現的時候,幾乎震住了...

快速平方根演算法

在3d圖形程式設計中,經常要求平方根或平方根的倒數,例如 求向量的長度或將向量歸一化。c數學函式庫中的sqrt具有理想的精度,但對於3d遊戲程式來說速度太慢。我們希望能夠在保證足夠的精度的同時,進一步提高速度。carmack在quake3中使用了下面的演算法,它第一次在公眾場合出現的時候,幾乎震住了...

整數平方根的計算 二

摘要 演算法 這個程式的主要演算法是牛頓迭代法。他首先得到乙個平方根的初始值,然後使用牛頓迭代法逐步求精,在計算過程中,始終用兩個整數的比表示整數平方根的值。最後,它轉換分數表示的平方根為10進製字串。說明 該文有待完善。效能分析 對比pifast,它的效能仍然不是很好,我特意分析了這個程式各個部分...