求算术平方根的实现方法

二分法与梯度法求平方根

一个比较适合warm up的问题

二分法实现

sqrt的实现有两种思路,第一种是使用二分法,类似心算,即取输入的一半,若平方后大于输入,则再取一半,若平方小于输入,则取上次和当前估计的平均,如此逼近,但是要注意0-1区间,需改变求值与左右界的更新方式。

epsilon = 1e-9
def sqrt_Bisection(y):
    if y < 0.0:
        raise ValueError("input is not non-negative")
    if y == 0.0 or y == 1.0:
        return y
    if y < 1:
        left = y
        right = 2 * y
        mid = (left + right) / 2
        res = mid ** 2 - y
        while abs(res) > epsilon:
            if res < 0:
                left = mid
                right = 2 * mid
            elif res > 0:
                right = mid
            mid = (left + right) / 2
            res = mid ** 2 - y
        return mid
    if y > 1:
        left = 0
        right = y
        mid = (left + right) / 2
        res = mid ** 2 - y
        while abs(res) > epsilon:
            if res < 0:
                left = mid
            elif res > 0:
                right = mid
            mid = (left + right) / 2
            res = mid ** 2 - y
        return mid

数值优化思路

这可视为最优估计问题,
y=f(P) y=f(P) y=f(P)
求给定观测y下参数P的最优估计,
f(P)=P2 f(P)=P^2 f(P)=P2
此问题,高斯牛顿法与梯度下降法得出同样的形式,
ϵ=f(P)−yΔ=−J−1ϵJ=2PP=P+Δ \epsilon=f(P)-y \\ \Delta = -J^{-1}\epsilon \\ J = 2P \\ P = P+\Delta ϵ=f(P)yΔ=J1ϵJ=2PP=P+Δ

epsilon = 1e-9
def sqrt_Gradient(y):
    if y < 0:
        raise ValueError("input is not non-negative")
    if y == 0.0 or y == 1.0:
        return y
    x = y / 2
    # $$/delta = -inv(J)/epsilon$$
    delta = (y - x ** 2) / (2 * x)
    while abs(y - x ** 2) > epsilon:
        x += delta
        delta = -(x ** 2 - y) / (2 * x)
    return x
在C++中,有多种方法可以算术平方根。 ### 使用`<cmath>`库中的`sqrt`函数 这是一种较为简单直接的方法,适用于需要精确浮点数结果的场景。以下是示例代码: ```cpp #include <iostream> #include <cmath> int main() { int n; std::cin >> n; // n的算术平方根 double r = std::sqrt(n); std::cout << r << std::endl; return 0; } ``` 此代码通过`std::sqrt`函数计算输入整数`n`的算术平方根,并将结果存储在`r`中输出。`std::sqrt`函数在`<cmath>`库中定义,它能处理浮点数和整数类型的输入,返回一个`double`类型的结果,该结果是输入值的算术平方根[^1]。 ### 二分查找法 当需要一个非负整数的算术平方根,并且结果只保留整数部分时,可以使用二分查找法。以下是示例代码: ```cpp #include <iostream> int mySqrt(int x) { if (x == 1 || x == 0) { return x; } int l = 0, r = x, ans = -1; while (l <= r) { int mid = (l + r) / 2; if ((long long)mid * mid <= x) { ans = mid; l = mid + 1; } else { r = mid - 1; } } return ans; } int main() { int x; std::cin >> x; int num = mySqrt(x); std::cout << num << std::endl; return 0; } ``` 这段代码实现了一个自定义的`mySqrt`函数,使用二分查找的思想来计算非负整数`x`的算术平方根的整数部分。通过不断缩小查找范围,最终找到满足`mid * mid <= x`的最大整数`mid`,并将其作为结果返回。在`main`函数中,接收用户输入的整数`x`,调用`mySqrt`函数计算结果并输出[^3]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值