【剑指Offer】计算X的平方根——两种解法

计算X的平方根——两种解法

题目描述:

计算x的平方根,保留8位小数。
输入:5
输出:2.23606797

解题思路

本题主要考察对x求平方根的数学思想。在大多数语言中都提供了数学方法的实现。那么要求一个数的平方根,是怎么实现的呢?实际上求平方根的算法方法主要有两种:二分法(binary search)牛顿迭代法(Newton iteration)

二分法

以计算5的平方根为例:

  1. 计算5的一半,即5/2=2.5
  2. 平方验证:2.5*2.5=6.25>5,则说明5的平方根的上限为2.5
  3. 计算2.5的一半,即2.5/2=1.25
  4. 平方验证:1.25*1.25=1.5625<5,说明5的平方根的下限为1.5625
  5. 计算2.5-(2.5-1.25)/2的一半,即1.875
  6. 平方验证:1.875*1.875=3.515625<5,得到当前下限1.875

每次得到当前值和5进行比较,并且记录下限和上限,依次迭代,逐渐逼近平方根。代码如下:

from math import sqrt
# 使用二分法计算x的平方根
def mySqrt_1(x):
    # 使用math库的sqrt方法计算一个最终结果作为比较对象
    base = sqrt(x)
    y = x / 2.0  # 折半
    low = 0.0  # 平方根的下界
    up = x * 1.0  # 平方根的上届
    # 当y与最终结果的误差小于0.000000001,终止循环
    while abs(y - base) > 0.00000001:
        # 当y*y>x,说明x的平方根的上界为y,否则下届为y
        if y * y > x:
            up = y
            y = low + (y - low) / 2  # 向下折半压缩空间
        else:
            low = y
            y = up - (up - y) / 2  # 向上折半压缩空间
    return round(y, 8)  # 保留8位小数

牛顿法

仔细思考一下就能发现,我们需要解决的问题可以从两个角度理解:

  • 从函数意义上理解:我们是要求函数f(x) = x²,使f(x) = num的近似解,即x² - num = 0的 近似解。
  • 从几何意义上理解:我们是要求抛物线g(x) = x² - num与x轴交点(g(x) = 0)最接近的点。

我们假设g(x0)=0,即x0是正解,那么我们要做的就是让近似解x不断逼近x0,这是函数导数的定义:
f ′ ( x 0 ) = lim ⁡ x → x 0 f ( x ) − f ( x 0 ) x − x 0 f'(x_0)=\lim_{x\rightarrow x_0} \frac{f(x)-f(x_0)}{x-x_0} f(x0)=xx0limxx0f(x)f(x0)
可以由此得到:
x 0 ≈ x − f ( x ) f ′ ( x 0 ) x_0\approx x - \frac{f(x)}{f'(x_0)} x0xf(x0)f(x)
对于一般的情况:
推到过程

代码如下:

# 使用逐次逼近的方法,即牛顿法,原理参考高等数学第一章:微积分与导数
def mySqrt_2(x):
    # 使用math库的sqrt方法计算一个最终结果作为比较对象
    base = sqrt(x)
    y = x / 2.0
    while abs(y - base) > 0.00000001:
        y = ((y * 1.0) + (1.0 * x) / y) / 2.0000
    return round(y, 8)

效果检验

效果检验

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

镰刀韭菜

看在我不断努力的份上,支持我吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值