牛顿迭代法(Newton’s Method)

洛谷:P1024
OJ: LD1086

牛顿迭代法简介

牛顿迭代法是一种用于求解方程 f(x)=0f(x)=0 的数值方法,通过迭代逼近方程的根。其基本公式为:

\(x_{n+1}=x_n-\frac{f(x_n)}{f'(x_n)}\)

特点

  • 收敛速度快(二阶收敛),但依赖初始猜测 x0
  • 需要函数 f(x)可导,且导数 f′(x)易于计算。

假设我们需要求解方程 f(x)=x2−2=0即求 \(\sqrt{2}\)​):

根据迭代基本公式,迭代公式简化为:\(x_{n+1}=x_{n}-\frac{x_{n}^{2}-2}{2x_{n}}=\frac{1}{2}(x_{n}+\frac{2}{x_{n}})\)

牛顿迭代法代码实现求对n求平方根:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
/**************************************************************** 
 * 代码作者: Alex Li
 * 创建时间: 2025-04-09 12:32:34
 * 最后修改: 2025-04-09 16:30:30
 * 文件描述: 牛顿迭代法计算平方根(优化版)
****************************************************************/

#include <iostream>  // 输入输出
#include <cmath>     // 数学函数(如 abs, sqrt)
#include <iomanip>   // 控制输出格式(如 setprecision)
using namespace std;
 
 /* @param n     待求平方根的数(必须 >= 0)
 * @param p     用户指定的初始精度容差(如 1e-5)
 * @return      返回 n 的平方根近似值
 */
double newtonSqrt(double n, double p) {
    // 输入验证
    if (n < 0) {
        cerr << "Error: Cannot compute square root of a negative number." << endl;
        return NAN;  // 返回非数值
    }
    if (n == 0) return 0;  // 0 的平方根是 0
    p = 1e-5;
    // 动态调整精度(避免对小数值的过度计算)
    double tolerance = (n > 1e6) ? p * 10 : p;  // 大数放宽精度要求

    // 初始猜测值优化:选择 x0 = n / 2 比 x0 = n 更高效
    double x = n / 2.0;
    double root;
    int max_iter = 100;  // 迭代安全上限,防止无限循环
    int iter = 0;  //记录迭代次数

    while (iter < max_iter) {
        iter++;
        root = 0.5 * (x + (n / x));  // 牛顿迭代公式
        if (abs(root - x) < tolerance) {
            cout << "Converged after " << iter << " iterations." << endl;
            return root;
        }
        x = root;  // 更新猜测值
    }

    
    return root;  // 返回当前最优解
}

int main() {
    double n;
    cout << "Enter a non-negative number: ";
    cin >> n;

    double result = newtonSqrt(n);  // 使用默认精度 1e-5

    // 输出结果(对比标准库实现)
    cout << fixed << setprecision(8);
    cout << "Newton's method: " << result << endl;
    cout << "Standard sqrt(): " << sqrt(n) << endl;

    return 0;
}
Scroll to Top