牛頓法求平方根
原理
計(jì)算機(jī)常用循環(huán)來計(jì)算F的平方根.從某個猜測的x值開始,根據(jù)x^2與F的近似度來調(diào)整x,產(chǎn)生一個更好的猜測:
x -= (x * x - F) / (2 * x)
重復(fù)調(diào)整過程,猜測的結(jié)果會越來越精確,得到的答案越發(fā)的趨近實(shí)際的平方根. 我們可以設(shè)定精度,控制計(jì)算結(jié)果與實(shí)際結(jié)果的偏差.
實(shí)現(xiàn)
package main
import (
"fmt"
"math"
)
func Sqrt(F float64) float64 {
x := 1.0
for math.Abs(x * x - F) > 1e-10 {
x -= (x * x - F) / (2 * x);
}
return x
}
func main() {
fmt.Println("牛頓法求平方根:Sqrt(10) = ", Sqrt(10))
fmt.Println("庫函數(shù)求平方根:Sqrt(10) = ", math.Sqrt(10))
}
補(bǔ)充知識:X的平方根的golang實(shí)現(xiàn)
實(shí)現(xiàn) int sqrt(int x) 函數(shù)。
計(jì)算并返回 x 的平方根,其中 x 是非負(fù)整數(shù)。
由于返回類型是整數(shù),結(jié)果只保留整數(shù)的部分,小數(shù)部分將被舍去。
輸入: 4
輸出: 2
輸入: 8
輸出: 2
說明: 8 的平方根是 2.82842...,由于返回類型是整數(shù),小數(shù)部分將被舍去。
首先遇到這種題目肯定要想到使用內(nèi)置得api來解答:
//使用api來求解
func mySqrt(x int) int {
f := float64(x)
ff := math.Sqrt(f)
return int(ff)
}
其次我們可以使用牛頓法求平方根:
牛頓法:(以本題為例子)
計(jì)算平方根,其實(shí)就是計(jì)算
x^2 =n
的解
令f(x)=x2-n,相當(dāng)于求解f(x)=0的解,如上圖所示。
首先取x0,如果x0不是解,做一個經(jīng)過(x0,f(x0))這個點(diǎn)的切線,與x軸的交點(diǎn)為x1。
同樣的道理,如果x1不是解,做一個經(jīng)過(x1,f(x1))這個點(diǎn)的切線,與x軸的交點(diǎn)為x2。
以此類推。
以這樣的方式得到的xi會無限趨近于f(x)=0的解。
判斷xi是否是f(x)=0的解有兩種方法:
一是直接計(jì)算f(xi)的值判斷是否為0,二是判斷前后兩個解xi和xi-1是否無限接近。
經(jīng)過(xi, f(xi))這個點(diǎn)的切線方程為f(x) = f(xi) + f'(xi)(x - xi),其中f'(x)為f(x)的導(dǎo)數(shù),本題中為2x。令切線方程等于0,即可求出xi+1=xi - f(xi) / f'(xi)。
繼續(xù)化簡
xi+1=xi - (xi2 - n) / (2xi) = xi - xi / 2 + n / (2xi) = xi / 2 + n / 2xi = (xi + n/xi) / 2
迭代公式就已經(jīng)出來了
x = (x + n/x) / 2
那么代碼:
//使用牛頓法求平方根
func mySqrt1(x int) int {
res := x
//牛頓法求平方根
for res*res > x {
res = (res + x/res) / 2
}
return res
}
以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。如有錯誤或未考慮完全的地方,望不吝賜教。
您可能感興趣的文章:- 使用go求冪的幾種方法小結(jié)
- 淺談Go語言中的次方用法
- Golang 運(yùn)算符及位運(yùn)算詳解
- golang指數(shù)運(yùn)算操作
- golang切片反序?qū)嵗?/li>