求一个数的开平方
我们假设这个数是a
,如何先快速求出√a
的值?
我们可以把这个题目转化成一个几何问题。如下图:
可以转换为,求公式Y = X^2 - a
,(√a,0)
的值。
- 我们现在抛物线上任意取一点
(x0,x0^2 - a)
, 然后基于这一点画一个切线,切线的方程记为Y = KX + b
。 - 切线的斜率
K
,我们可以对抛物线求导,得到K = 2 * x0
- 带入到切线的方程可以得
Y = 2 * x0 * X + b
- 因为切线经过点
(x0,x0^2 - a)
,带入切线方程,就有x0^2 - a = 2 * x0^2 + b
- 转而得到
b = -x0^2 - a
- 然后带入到之前的切线的方程
Y = 2 * x0 * X + b
可得Y = 2 * x0 * X - x0^2 - a
,把。 - 把
(x1, 0)
带入上面的切线方程得到x1 = x0^2 + a / (2 * x0)
- 重复上面的步骤,在抛物线上取一点
(x1,x1^2 - a)
, 最终可以得到x2 = x1^2 + a / (2 * x1)
- 随着这样不停的递归迭代。
x
值会慢慢趋向于(√a,0)
(因为切线是线性逼近线与抛物线只有一个交点)
最终用代码实现的牛顿开方法如下:
const det = 1e-5 // 误差多少
func sqrt(a float64) float64 {
x0 := a
for {
x1 := (x0*x0 + a) / (2 * x0)
if math.Abs(x1-x0) < det {
return x1
}
x0 = x1
}
}