You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于指定公式的C语言π值计算精度停滞问题排查

π值计算精度停滞问题的分析与解决

问题背景

在CodeBlocks环境中用C语言实现π值计算,目标是达到10位小数精度(3.1415926535),采用迭代公式并优化内存分配,但迭代过程中结果在3.1415926431后停止增长,无法达到目标精度,迭代仍持续进行,不确定问题源于数学层面还是变量溢出。

问题根源

  • 公式收敛速度过慢:你使用的是Wallis公式的迭代形式(π/2 = ∏(4n²/(4n²-1))),该公式收敛极慢,要达到10位小数精度需要数万甚至更多次迭代。
  • 浮点数精度限制:double类型的有效精度约为15-17位十进制数,但当迭代次数足够大时,4n²/(4n²-1)与1的差值极小(小于double的最小可表示增量),此时乘以resultNumber无法改变其值,导致计算结果停滞。
  • 终止条件的精度偏差:手动定义的pi = 3.1415926535本身是近似值,且使用pow(10,-10)计算阈值会引入额外精度误差,不如直接使用常量1e-10。

修复与优化方案

方案1:更换收敛更快的计算公式

推荐使用Machin公式,它能在极少迭代次数内达到高精度:
π = 4 × (4×arctan(1/5) - arctan(1/239))
arctan函数可通过泰勒级数的优化形式计算,收敛速度远快于Wallis公式。

方案2:优化现有代码(若坚持使用Wallis公式)

  • 启用标准库高精度π值:在包含math.h前定义#define _USE_MATH_DEFINES,使用M_PI代替手动输入的近似值。
  • 替换阈值计算:用1e-10代替pow(10,-10),提升效率与精度。
  • 改用long double类型:提升浮点数精度,延迟停滞出现的时间,但无法解决Wallis公式收敛慢的本质问题。

优化后代码示例(Machin公式实现)

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

#define _USE_MATH_DEFINES

// 计算arctan(x),使用泰勒级数优化(交替级数,直到项小于1e-12)
long double arctan(long double x) {
    long double res = 0;
    long double term = x;
    long double x_sq = x * x;
    int sign = 1;
    int n = 1;
    while (fabsl(term) > 1e-12) {
        res += sign * term / n;
        term *= x_sq;
        sign *= -1;
        n += 2;
    }
    return res;
}

int main() {
    double time_spent = 0.0;
    clock_t begin = clock();

    long double pi = 4 * (4 * arctan(1.0L/5) - arctan(1.0L/239));
    printf("π值:%.10Lf\n", pi);

    clock_t end = clock();
    time_spent += (double)(end - begin) / CLOCKS_PER_SEC;
    printf("耗时:%f秒\n", time_spent);
    return 0;
}

关键说明

  • Machin公式仅需几十次迭代即可达到10位以上精度,远优于Wallis公式的数万次迭代,同时避免了浮点数精度停滞的问题。
  • long double类型比double提供更高的精度(部分平台为80位),适合高精度计算场景。

内容的提问来源于stack exchange,提问作者Miggo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 11:45:34