不使用库函数sqrt求平方根详解(牛顿迭代法) C语言入门
歡迎關注筆者,你的支持是持續更博的最大動力
目錄
- 問題描述
- 思路
- 代碼(解法一)
- 代碼(解法二)
- 牛頓迭代法公式解析
- 相關內容
- 其他
問題描述
求平方根(牛頓迭代法),公式如下:
xn+1=(xn+a/xn)/2x_{n+1} = (x_n + a/x_n)/2xn+1?=(xn?+a/xn?)/2
輸入:a
輸出:a\sqrt{a} \quada?
思路
初步思路: 把問題具像化——求正方形邊長
正方形: 邊長2=面積邊長^2=面積邊長2=面積 ,邊長=面積邊長=\sqrt{面積} \quad邊長=面積?
所以問題可轉化為求面積為 aaa 的正方形的邊長 xxx。
問:不開根號,怎么求正方形邊長?
答:猜一個 xxx,看是不是正方形,然后繼續猜。
繼續猜怎么猜?用公式:
xnew=(x+a/x)/2x_{new} = (x + a/x)/2xnew?=(x+a/x)/2
即,長新=(長+寬)/2長_新 = (長+ 寬)/2長新?=(長+寬)/2
判斷當前長、寬是否接近:
|x?x-x?axa\over xxa?| < ?\epsilon????? 或???? |xnew?xx_{new}-xxnew??x|< ?\epsilon?
(設?\epsilon?=0.001 或其他數,控制精度)
不斷用公式猜(更新),則長、寬會越來越接近,形狀越來越像正方形,即 xnewx_{new}xnew? 會逐漸趨近于a\sqrt{a} \quada?。
如,求8的平方根:
我們知道8\sqrt{8} \quad8?是一個無理數 ≈2.8284271247462...\approx 2.8284271247462...≈2.8284271247462...,會一直計算下去。而設置了精度?\epsilon?,就可以知道什么時候停止計算,認為找到精確根。
?
判斷當前長、寬是否接近的2種方法,會使代碼略微不同,如下:
代碼思路一
- 設置?\epsilon? 用以控制精度;
- 判斷所求數 a 是否為正:
- 若a > 0, 可求平方根;
- 假設長、寬初始值:
x = a/2 ???? y = a/x - 只要|x?yx-yx?y|> ?\epsilon? ,長寬不夠接近,迭代計算。
迭代終止條件:|x?yx-yx?y|< ?\epsilon?
- 若a < 0, 不可求平方根,提示輸入數不可為負。
代碼(解法一)
double eps = 0.001; //epsillon用以控制計算精度:若找到的長寬之差小于0.001,則認為足夠精確 int main(){double a;cin >> a; //接收鍵盤輸入的數a (cin:輸入 cout:輸出)if (a >= 0){ //若a為正,可求平方根double x = a/2, y = a/x; //猜測矩形的長、寬,并初始化while (x - y > eps || y - x > eps){ //只要精度未達要求,長寬不夠接近,就繼續迭代y = a/x; //每次迭代先用原來的長x更新寬yx = (x + y)/2; //再更新長x(公式)//cout << x << endl; //加上這行可看每次迭代更新的x,也就是近似根(endl:換行)}cout << x << endl; //若|x - y| < eps,迭代完畢,輸出精確根(endl:換行)}else //若a為負,不可求平方根cout << "It can't be nagetive." << endl; //輸出提示語句 (endl:換行)return 0; }代碼思路二
- 設置?\epsilon? 用以控制精度;
- 判斷所求數 a 是否為正:
- 若a > 0, 可求平方根;
- 猜測根的兩個值xn+1x_{n+1}xn+1?和xnx_{n}xn?,以便至少進入一次迭代計算。
設:xn+1x_{n+1}xn+1?為x,????x = a/2
???????xnx_nxn?為 lastX,?lastX = x + 1 + eps
(上述假定可使 lastX - x > eps,xn+1x_{n+1}xn+1?和xnx_{n}xn?不夠接近,可往下進行至少一次迭代計算) - 只要|lastX?xlastX-xlastX?x|> ?\epsilon? ,相鄰兩次計算結果不夠接近,繼續迭代計算。
迭代終止條件:|lastX?xlastX-xlastX?x|< ?\epsilon?
- 若a < 0, 不可求平方根,提示輸入數不可為負。
代碼(解法二)
double eps = 0.001; //epsillon用以控制計算精度,若找到的假設的平方根和真實平方根直接的差距小于0.001,就足夠精確 int main(){double a;cin >> a; //接收鍵盤輸入的數a (cin:輸入 cout:輸出)if (a >= 0){ //若a為正,可求平方根double x = a/2, lastX = x + 1 + eps; //猜測之前相鄰兩次計算結果x和lastX,并初始化while (x - lastX > eps || lastX - x > eps){ //只要精度未達要求,相鄰兩次計算結果不夠接近,繼續迭代lastX = x; //每次迭代先更新lastX,把上次結果變成上上次計算結果x = (x + a/x)/2; //再更新X(公式)//cout << x << endl; //加上這行可看每次迭代更新的x,也就是近似根(endl:換行)}cout << x << endl; // |x - lastX| < eps,迭代完畢,輸出精確根}else //若a為負,不可求平方根cout << "It can't be nagetive." << endl;//輸出提示語句 (endl:換行)return 0; }牛頓迭代法公式解析
Lnew=(L+A/L)/2L_{new} = (L + A/L)/2Lnew?=(L+A/L)/2
假設存在一個長方形,
面積:AAA ???????????長:LLL ???????????寬:a/La/La/L
那么,
LnewL_{new}Lnew?:(L+a/L)2(L+ a/L)\over22(L+a/L)? 即 (長+寬)2(長+寬)\over 22(長+寬)?
在面積不變的情況下, 一直計算,LnewL_{new}Lnew?會越來越接近正方形的邊長,一直計算下去則可得到A\sqrt{A} \quadA?。
正方形面積 = 邊長 × 邊長
邊長=正方形面積\sqrt{正方形面積} \quad正方形面積?
邊長為正方形面積的平方根。
圖片來源: 康奈爾大學課件
相關內容
- 用C/C++自帶庫函數sqrt求平方根
其他
日常vlog: 點這里去B站~
總結
以上是生活随笔為你收集整理的不使用库函数sqrt求平方根详解(牛顿迭代法) C语言入门的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: jQuery/javascript实现简
- 下一篇: 输出特殊形状的图形