求 √a 等價解 f(x) = x² - a = 0。
牛頓迭代公式:x_{n+1} = x_n - f(x_n)/f'(x_n) = (x_n + a/x_n) / 2。
#include
#include
double sqrt_newton(double a) {
if (a < 0) return NAN;
if (a == 0) return 0;
double x = a; // 初值:a 本身 (a>=1) 或 1 (a<1)
if (x < 1) x = 1;
double prev;
do {
prev = x;
x = (x + a / x) * 0.5;
} while (fabs(x - prev) > 1e-10); // 相對/絕對誤差雙重判斷更強健
return x;
}
int main() {
double a;
printf("請輸入非負數: ");
if (scanf("%lf", &a) != 1 || a < 0) {
printf("輸入錯誤\n");
return 1;
}
double result = sqrt_newton(a);
printf("√%.10f = %.10f\n", a, result);
printf("庫函數 sqrt = %.10f\n", sqrt(a));
printf("誤差 = %.2e\n", fabs(result - sqrt(a)));
return 0;
}
| 細節 | 處理方式 |
|---|---|
| 初值選擇 | x = a (a≥1) 或 x = 1 (a<1),避免除零、加速收斂 |
| 終止條件 | fabs(x - prev) > EPS,EPS=1e-10 (double) 足夠 |
| 特殊值 | a=0 直接回 0;a<0 回 NAN 並設 errno=EDOM |
| 除零保護 | 迭代中 x 永不為 0 (單調遞減趨近 √a > 0) |
| 效能 | 二次收斂,雙精度通常 5~6 次迭代達機器精度 |