You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

浮点数精度问题导致循环无法终止的技术求助

浮点数精度问题导致循环无法终止的技术求助

嘿,我来帮你捋捋这个循环停不下来的问题哈!

首先看你的需求:你想当两次迭代的数值变化小于小数点后14位(也就是差值小于1e-14)时让循环终止,但你的代码逻辑加上浮点数本身的精度特性,刚好让循环停不下来。

先说说你代码里的核心问题:

  • 循环条件完全写反了!你用stand_n - stand <= 10e-15作为循环继续的条件,意思是“只要两次值的差小于等于1e-14,就继续循环”——这和你想要的“差小于1e-14就停止”完全相反啊!
  • 另外,浮点数的比较最好用绝对值,虽然这个迭代是单调收敛到√2的,不会出现负差值,但养成这个习惯能避免很多潜在问题。
  • 还有double类型的精度限制:double的有效位数大概是15-17位,当两个值的差小到double无法区分时,它们在内存里就是同一个值了,此时差值为0,你的条件会一直满足,循环就无限跑下去了。

再看你的输出,当数值收敛到1.41421356237309之后就不再变化了,这是因为double已经没法表示更精确的数值了,此时stand_n和stand完全相等,差值为0,你的循环条件0 <= 1e-14永远成立,自然停不下来。

给你改了一份代码,你试试:

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

int main (void)
{
    double stand = 1.0;
    // 先算出第一个迭代值
    double stand_n = 1.0 / stand + stand / 2.0;
    printf("%.14lf\n", stand_n);

    // 当两次值的差的绝对值大于1e-14时,继续迭代
    while (fabs(stand_n - stand) > 1e-14)
    {
        // 把当前值赋值给旧值
        stand = stand_n;
        // 计算新的迭代值
        stand_n = 1.0 / stand + stand / 2.0;
        printf("%.14lf\n", stand_n);
    }
}

这个代码的逻辑是:先计算第一个新值,然后每次判断当前值和上一次值的差,如果差还足够大(大于1e-14),就继续迭代;当差小到阈值以下时,直接退出循环,完美符合你的需求。

备注:内容来源于stack exchange,提问作者Tasos Charto

火山引擎 最新活动