一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第12天,点击查看活动详情。
平方根定义
有一个, 如果有, 那么 m 就是 n 的平方根。我们知道,m一般有两个,正负各一个。这里规定一下,本文讲的是
一个粗劣的方法
比如说,我们要计算 这个的值。可以这样
- 先比较 , 显然
- 再取一半44 , 比较 , 显然
- ...
- ...
- ...
- 取 11, 比较 , 显然
- 取 5.5, 比较 , 显然
- 好,那么往上取,11和5.5取一个中间数,8.25
- 比较 ,
- 再往上取,
- 比较 ,
- 此时,往下取
- 比较 ,
- 此时,往上取
- 比较 , , 此时很逼近了
- 继续此步骤
- ...
- ...
- ...
- ...
- ...
总不能无限循环下去吧,所以我们搞一个终止条件,, 我们就认为找到了。
代码实现(Golang)
func sqrt(input float64) float64 {
var x float64 = input
up, down := input, float64(1)
var compare = func(a, b float64) int {
if a > b {
if a-b < 0.001 {
return 0
}
return 1
}
if b-a < 0.001 {
return 0
}
return -1
}
for loop := 0; ; loop++ {
if res := compare(x*x, input); res > 0 {
up = x
x = (up + down) / 2
} else if res < 0 {
down = x
x = (up + down) / 2
} else {
fmt.Println("loop", loop, x)
return x
}
}
}
这里值得关注的有下面几点:
-
- 这个函数只能计算 ,因为对于 , 此时迭代方向应该翻转。
-
- 如果想计算, 只需要根据一个公式:, 也就是说,先算 的平方根,然后倒过来就行了。这是因为
-
- 注意其中的
compare函数,我们这里精确到
- 注意其中的
牛顿迭代法
我们这里给出一个递推公式:
比如说要计算。
这个递推过程,如下:
- 取 代入上式计算
- 取 代入上式计算
- 依次往下一直计算
- 计算次数越多,就越逼近 。那么也是要搞一个终止条件的,这个根据你需求的精确度来定。
牛顿迭代法代码(Golang)
这里把上面的compare函数弄到外面去
func compare(a, b float64) int {
if a > b {
if a-b < 0.001 {
return 0
}
return 1
}
if b-a < 0.001 {
return 0
}
return -1
}
func sqrt_newton(input float64) float64 {
var x float64 = 1
for loop := 0; ; loop++ {
x = 0.5 * (x + input/x)
fmt.Println(loop, x)
if res := compare(x*x, input); res == 0 {
return x
}
}
}
这个注意点:
compare的精确度也是0.001- 我们用作为例子,经过运行,我们发现,逼近同样的精确度时,牛顿法只用了5次。
- 上面的粗劣迭代法,用了20次。
- 这里可见牛顿法快多了。