【问题标题】:Calculating $\sqrt[3]{x}$ with Babylonian method用巴比伦方法计算 $\sqrt[3]{x}$
【发布时间】:2026-02-13 13:05:01
【问题描述】:

考虑一下我在 C 中实现巴比伦方法的尝试:

int sqrt3(int x) {
    double abs_err = 1.0;
    double xold = x;
    double xnew = 0;

    while(abs_err > 1e-8) {
        xnew =  (2 * xold + x/(xold* xold))/3;
        abs_err= xnew-xold;
        if (abs_err < 0) abs_err = -abs_err;
        xold=xnew;
    }
    return xnew;
} 
int main() {
    int a;

    scanf("%d", &a);
    printf(" Result is: %f",sqrt3(a));
    return 0;   
}

结果是 x=27: 0.0000? 我的错在哪里?

【问题讨论】:

  • 1/3 执行整数(截断)除法,因此结果为0。要么执行 1.0/3 之类的操作,要么将 /3 移动到表达式的末尾(因此 / 的 lhs 是 double 而不是 int)。
  • 谢谢:但还是0.0000
  • 我写道:xnew=(2 * xold + x/(xold* xold))/3;
  • xalt 在哪里声明?全局变量?
  • 请注意,SO 站点不提供 MathJax,因此它不会解释 LaTeX。顺便说一句,它似乎是一个 cube 根,而不是 sqrt3。

标签: c implementation


【解决方案1】:

虽然函数返回 int,但该值将使用 wrong format specifier%f 而不是 %d 打印。

将签名(和名称,如果可以的话)更改为 this

double cube_root(double x) { ... }

如果您真的想要int,或者更改格式说明符。

【讨论】:

  • 谢谢 :) 我没有看到我的返回类型是 int :)
【解决方案2】:

根据tutorialspoint 的解释,基本思想是实现求解非线性方程的 Newton Raphson 方法,恕我直言,下面的代码更清楚地显示了这一事实。由于已经有一个公认的答案,我添加这个答案仅供将来参考。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

double rootCube( double a)
{
    double x = a;
    double y = 1.0;
    const double precision = 0.0000001;
    while(fabs(x-y) > precision)
    {
        x = (x + y) / 2.0;
        y = a / x / x;
    }
    return x;
}

int main(int argc, const char* argv[])
{
    if(argc > 1)
    {
        double a = 
            strtod(argv[1],NULL); 
        printf("cubeRoot(%f) = %f\n", a, rootCube(a));
    }

    return 0;
}

在这里,与问题的原始代码相比,更明显的是,xy 是界限,正在改进直到找到足够准确的解决方案。

通过修改 while 块中的行,其中 y 正在更新,此代码也可用于求解类似的方程。例如,对于求平方根,这行代码如下所示:y = a / x

【讨论】:

  • 请注意,虽然有几种方法可以改进 OP 的代码(初学者的错误估计),但本教程点链接中显示的算法看起来并不像牛顿法。至少它似乎没有二次收敛速度(参见例如here),它更像是一种二分法。
  • @Bob__ 我真的应该避开那个 tutorialspoint 网站。这不是我第一次在那里发现错误的信息。感谢您指出。