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

C语言无穷级数求π:不同精度对应项数计算代码故障求助

问题描述
  • 需求:通过莱布尼茨无穷级数计算π,打印每一项的π近似值表格,求解首次得到3.14、3.141、3.1415、3.14159时所需的级数项数。
  • 现有问题:单精度(3.14)计算代码可正常运行,对应项数为30;但扩展多循环代码后,仅输出Calculating the value of pi.后无后续输出。
  • 限制条件:禁止使用prec、trunc等函数。
问题根源分析

修改后的代码存在三个核心问题:

  1. 精度丢失导致死循环:所有循环中都执行pi = (round(pi * 100)) / 100;,强制将pi截断到两位小数,后续更高精度的目标(如3.141、3.1415)永远无法达到,进入死循环。
  2. 浮点数直接比较的风险:用pi != 3.141000这类浮点数直接相等判断,会因浮点数精度误差导致循环逻辑异常。
  3. 项数记录错误:所有精度的项数都使用同一个n变量,无法分别记录各精度首次出现的项数。
修复后的代码
#include <stdio.h>
#include <math.h>

int main() {
    int n = 1; // n代表当前级数项数,初始为第1项(对应4*1)
    double pi = 4.0; // 第1项的pi值
    // 记录各精度首次出现的项数,初始为-1表示未找到
    int cnt_2 = -1, cnt_3 = -1, cnt_4 = -1, cnt_5 = -1;
    // 目标精度对应的放大后的值(避免浮点数直接比较)
    const double target_2 = 3.14 * 100;
    const double target_3 = 3.141 * 1000;
    const double target_4 = 3.1415 * 10000;
    const double target_5 = 3.14159 * 100000;

    printf("Calculating the value of pi.\n");
    printf("项数\t近似值\n");
    printf("------------------------\n");
    // 打印第1项
    printf("%d\t%.10f\n", n, pi);

    // 检查初始值是否满足精度(兜底逻辑)
    long long current_2 = llround(pi * 100);
    if (current_2 == (long long)target_2 && cnt_2 == -1) cnt_2 = n;

    while (cnt_5 == -1) { // 直到找到最高精度为止
        n++;
        // 莱布尼茨级数:第n项的符号是(-1)^(n+1),分母是2n-1
        double denominator = 2 * n - 1;
        double term = 4.0 / denominator;
        if (n % 2 == 0) {
            pi -= term; // 偶数项是减
        } else {
            pi += term; // 奇数项是加
        }

        // 打印当前项的近似值
        printf("%d\t%.10f\n", n, pi);

        // 检查各精度,仅记录首次达到的项数
        if (cnt_2 == -1) {
            long long curr = llround(pi * 100);
            if (curr == (long long)target_2) {
                cnt_2 = n;
            }
        }
        if (cnt_3 == -1) {
            long long curr = llround(pi * 1000);
            if (curr == (long long)target_3) {
                cnt_3 = n;
            }
        }
        if (cnt_4 == -1) {
            long long curr = llround(pi * 10000);
            if (curr == (long long)target_4) {
                cnt_4 = n;
            }
        }
        if (cnt_5 == -1) {
            long long curr = llround(pi * 100000);
            if (curr == (long long)target_5) {
                cnt_5 = n;
            }
        }
    }

    // 输出结果
    printf("\n首次达到各精度所需项数:\n");
    printf("pi≈3.14:%d项\n", cnt_2);
    printf("pi≈3.141:%d项\n", cnt_3);
    printf("pi≈3.1415:%d项\n", cnt_4);
    printf("pi≈3.14159:%d项\n", cnt_5);

    return 0;
}
代码关键说明
  1. 保留原始计算精度:不再中途截断pi的值,仅在判断精度时对pi进行放大和四舍五入,避免丢失后续计算所需的精度。
  2. 安全的精度判断:将pi和目标值分别乘以对应10的幂次(如100对应两位小数),转换为整数后比较,避免浮点数直接相等判断的误差。
  3. 独立记录项数:为每个精度设置单独的计数器,仅在首次达到该精度时记录当前项数。
  4. 循环终止条件:当最高精度(3.14159)的项数被找到后,终止循环,避免不必要的计算。
  5. 符合限制条件:未使用prec、trunc等禁用函数,若需替换llround,可手动实现四舍五入(如(long long)(pi*100 + 0.5))。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 10:11:34