【转】 不适用Sqrt函数开方,精度小于指定精度
給定一個數A,不使用sqrt函數,求A的開方,要求精度大于0.0001
該題有兩種方法求解:①牛頓迭代法;②二分法
①牛頓迭代法:
1.牛頓迭代法知識:
牛頓迭代法(Newton's method)又稱為牛頓-拉夫遜方法(Newton-Raphson method),它是牛頓在17世紀提出的一種在實數域和復數域上近似求解方程的方法。多數方程不存在求根公式,因此求精確根非常困難,甚至不可能,從而尋找方程的近似根就顯得特別重要。方法使用函數f(x)的泰勒級數的前面幾項來尋找方程f(x) = 0的根。牛頓迭代法是求方程根的重要方法之一,其最大優點是在方程f(x) = 0的單根附近具有平方收斂,而且該法還可以用來求方程的重根、復根。另外該方法廣泛用于計算機編程中。
設r是f(x) = 0的根,選取x0作為r初始近似值,過點(x0,f(x0))做曲線y = f(x)的切線L,L的方程為y = f(x0)+f'(x0)(x-x0),求出L與x軸交點的橫坐標 x1 = x0-f(x0)/f'(x0),稱x1為r的一次近似值。
過點(x1,f(x1))做曲線y = f(x)的切線,并求該切線與x軸交點的橫坐標 x2 = x1-f(x1)/f'(x1),稱x2為r的二次近似值。重復以上過程,得r的近似值序列,其中x(n+1)=x(n)-f(x(n))/f'(x(n))(公式1),稱為r的n+1次近似值,上式稱為牛頓迭代公式。
2.本題迭代公式推導
因為本題的題目是求開方,設待求開方的值為A,而開方后的值為x,則A與x的關系為A=x2,即求函數f(x)=x2-A=0的根。再根據上述的公式(1)即x(n+1)=x(n)-f(x(n))/f'(x(n)),將f(x),f”(x)帶入公式得到x(n+1) = x(n)-(x2-A)/2x=x(n)+(A/x- x)/2。
迭代公式:X(n+1)=X(n)+(A/X(n)-X(n))/2,其中A是輸入的待求被開方的數,X(n)是一次與A的開方相近的數,X(n+1)是下一次與A的開方相近的數 。
同理可以得到開三次放的迭代公式X(n+1)=Xn+(A/X^2-Xn)1/3 ,A、X(n)、X(n+1)意義與開平方相同。
①輸入初始值X(0),最簡單的是將X(0)定為1
②通過迭代公式計算與A相近的下一個開方數X(n),直到|A-X(n)|<0.001為止。?
| #include<iostream> using namespace std; double MySqrt(double A,double precision) //A為待開方的數,precision為精度 ???????? { ?????????????????? if(A<0) ??????????????????????????? throw"不能為負數!"; ?????????????????? double X=1; ?????????????????? while(abs(A-X*X)>precision) ?????????????????? { ??????????????????????????? X = X +(A/X-X)/2; ?????????????????? } ?????????????????? return X; ???????? } | int main() { ???????? double a; ???????? cout<<"輸入一個不小于0的數"; ???????? cin>>a; ???????? cout<<MySqrt(a,0.001)<<endl; ???????? return 0; } ? |
②牛頓二分法
一般地,對于函數f(x),如果存在實數c,當x=c時,若f(c)=0,那么把x=c叫做函數f(x)的零點。
解方程即要求f(x)的所有零點。
假定f(x)在區間(x,y)上連續
先找到a、b屬于區間(x,y),使f(a),f(b)異號,說明在區間(a,b)內一定有零點,然后求f[(a+b)/2],
現在假設f(a)<0,f(b)>0,a<b??
①如果f[(a+b)/2]=0,該點就是零點,
如果f[(a+b)/2]<0,則在區間((a+b)/2,b)內有零點,(a+b)/2>a,從①開始繼續使用
中點函數值判斷。
如果f[(a+b)/2]>0,則在區間(a,(a+b)/2)內有零點,(a+b)/2<b,從①開始繼續使用
中點函數值判斷。
這樣就可以不斷接近零點。
通過每次把f(x)的零點所在小區間收縮一半的方法,使區間的兩個端點逐步迫近函數的零點,以求得零點的近似值,這種方法叫做二分法。
| #include<iostream> using namespace std; double MySqrt(double A,double precision)//二分法 ???????? { ?????????????????? ?if(A<0)? throw "不能為負數!"; ?????????????????? double min =0,max = A; ?????????????????? double result = (min+max)/2; ?????????????????? while(abs(A-result*result)>precision) ?????????????????? {?????? if(A-result*result>0) ???????????????????????????????????? min =result; ??????????????????????????? else?? max = result; ??????????????????????????? result =(min+max)/2; } ?????????????????? return result; ???????? } ? |
總結
以上是生活随笔為你收集整理的【转】 不适用Sqrt函数开方,精度小于指定精度的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: U3D assetbundle加载与卸载
- 下一篇: C#中成员初始化顺序