首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

C 語言二分法求立方根:不調用 pow,手寫迭代逼近算法完整實現

     編輯:程式設計疑難解答

經典算法題:輸入實數 a,不使用 pow,輸出其立方根。本文提供基於二分法(區間折半)的完整 C 代碼,詳細解析邊界條件、正負數處理、精度控制,並對比牛頓迭代法優劣。

算法核心:二分法求解 x³ - a = 0

  • 函數 f(x) = x³ - a 單調遞增(導數 3x² ≥ 0)。
  • 目標:找到 f(x) = 0 的根,即 x = a^(1/3)。
  • 區間初始化:n=0, m=a(a>0);n=a, m=0(a<0)。
  • 迭代:取中點 x=(n+m)/2,根據 f(x) 正負縮小區間。

完整代碼(含註釋)

#include <stdio.h>

int main() {
    double a, n, m, x;
    scanf("%lf", &a);

    // 1. 初始化搜索區間
    if (a >= 0) {
        n = 0;
        m = a;
    } else {
        n = a;   // 負數立方根為負,區間 [a, 0]
        m = 0;
    }

    // 2. 二分迭代
    while (1) {
        x = (n + m) / 2.0;
        double fx = x * x * x - a;  // f(x) = x³ - a

        if (a >= 0) {
            if (fx <= 0) n = x;     // 根在右半區間
            else m = x;             // 根在左半區間
        } else {
            if (fx <= 0) m = x;     // 負數區間邏輯反轉
            else n = x;
        }

        // 3. 精度判斷:|x³ - a| < 1e-6
        if (fx <= 1e-6 && fx >= -1e-6) break;
    }

    printf("%lf %lf\n", x, x * x * x);  // 輸出立方根及驗證值
    return 0;
}

關鍵細節解析

細節處理方式原因
負數輸入區間設為 [a, 0],判斷邏輯反轉負數立方根為負,單調性不變但區間翻轉
a=0直接輸出 0避免除零/無限循環
精度控制|x³ - a| < 1e-6題目通常要求 6 位小數精度
溢出風險用 double,x*x*x 範圍足夠避免 int 溢出
無限循環保護可加最大迭代次數 (如 100 次)極端情況下防掛死

牛頓迭代法對比(收斂更快)

double cbrt_newton(double a) {
    if (a == 0) return 0;
    double x = a;  // 初始猜測
    for (int i = 0; i < 20; i++) {
        double prev = x;
        x = (2.0 * x + a / (x * x)) / 3.0;  // x_{n+1} = (2x_n + a/x_n²)/3
        if (fabs(x - prev) < 1e-12) break;
    }
    return x;
}
  • 收斂速度:二分法線性、牛頓法二次(雙指數),迭代次數少 10 倍。
  • 但牛頓法需處理 x=0 除零、初始值選擇敏感。
  • 面試/考試首推二分法:邏輯清晰、邊界可控、易於解釋。

測試用例

輸入: 8      輸出: 2.000000 8.000000
輸入: 27     輸出: 3.000000 27.000000
輸入: -8     輸出: -2.000000 -8.000000
輸入: 0.001  輸出: 0.100000 0.001000
輸入: 1000000 輸出: 100.000000 1000000.000000

避坑檢查清單

  1. scanf("%lf", &a) 讀 double 必須用 %lf。
  2. printf("%lf", x) 印 double 用 %lf (C99) 或 %f。
  3. 區間初始化覆蓋正負零。
  4. 精度判斷用 fabs(fx) < EPS 而非 fx == 0。
  5. 循環條件 while (m - n > EPS) 替代 while(1) 更規範。

二分法是數值計算的瑞士軍刀:單調函數求根、查找插入位置、浮點數二分答案,萬變不離其宗。掌握「區間初始化、中點測試、邊界收縮、精度終止」四步法,這類題目穩拿滿分。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved