求一个数的开平方

我们假设这个数是a,如何先快速求出√a的值?

我们可以把这个题目转化成一个几何问题。如下图:

image.png

可以转换为,求公式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
    image.png
  • 然后带入到之前的切线的方程 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
    }
}