计算根号二sqrt(2)

计算sqrt(2),要求精确到小数点后10位。常见的有二分法,牛顿迭代法,还有利用连分数的一些迭代法。

#include<iostream>
#include<vector>
#include<unordered_map>
#include <iomanip>
using namespace std;

const double eps = 1e-10;
// 二分法
double sqrt1(int x) {
    x = static_cast<double>(x);
    if(x == 0) return 0;
    double l = 1, r = x;
    while(r-l > eps) {
        // cout << l << " " << r << endl;
        double mid = (l + r) / 2;
        if(mid * mid <= x) l = mid;
        else r = mid;
    }
    return l;
}

// 牛顿迭代法 x_n+1 = x_n - f(x_n)/f'(x_n)
double sqrt2(int x) {
    x = static_cast<double>(x);
    double a = x, b = 0;
    while(abs(a - b) > eps) {
        b = a;
        a = (a + x / a) / 2;
    }
    return a;
}

// 连分数法
double sqrt3(int x) {
    x = static_cast<double>(x);
    double a = x, b = 0;
    while(abs(a - b) > eps) {
        b = a;
        a = (a + x / a) / 2;
    }
    return a;
}

// 连分数法2 \sqrt{x} = a + b/(2a + b/(2a+...))
double sqrt4(int x) {
    x = static_cast<double>(x);
    double a, b;
    for(int i = x;x > 0;i--) {  // 找到尽可能大的a
        if(i * i <= x) {
            a = i;
            break;
        } 
    }
    b = x - a * a;
    // cout << a << " " << b << endl;

    double pre = 0, cur = b/(2*a);
    while(abs(pre - cur) > eps) {
        pre = cur;
        cur = b/(2*a + cur);
    }
    return a + cur;
}

// 手算开平方
double sqrt5(int x) {
    // 不会实现
    return 0;
}

int main() {
    cout << setprecision(10) << sqrt1(2) << endl;
    cout << setprecision(10) << sqrt2(2) << endl;
    cout << setprecision(10) << sqrt3(2) << endl;
    cout << setprecision(10) << sqrt4(2) << endl;

    return 0;
}

参考链接:李永乐老师_手算开平方

posted @ 2022-02-17 20:16  Rogn  阅读(618)  评论(0编辑  收藏  举报