C语言无穷级数求π:不同精度对应项数计算代码故障求助
问题描述
- 需求:通过莱布尼茨无穷级数计算π,打印每一项的π近似值表格,求解首次得到3.14、3.141、3.1415、3.14159时所需的级数项数。
- 现有问题:单精度(3.14)计算代码可正常运行,对应项数为30;但扩展多循环代码后,仅输出
Calculating the value of pi.后无后续输出。 - 限制条件:禁止使用
prec、trunc等函数。
问题根源分析
修改后的代码存在三个核心问题:
- 精度丢失导致死循环:所有循环中都执行
pi = (round(pi * 100)) / 100;,强制将pi截断到两位小数,后续更高精度的目标(如3.141、3.1415)永远无法达到,进入死循环。 - 浮点数直接比较的风险:用
pi != 3.141000这类浮点数直接相等判断,会因浮点数精度误差导致循环逻辑异常。 - 项数记录错误:所有精度的项数都使用同一个
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; }
代码关键说明
- 保留原始计算精度:不再中途截断pi的值,仅在判断精度时对pi进行放大和四舍五入,避免丢失后续计算所需的精度。
- 安全的精度判断:将pi和目标值分别乘以对应10的幂次(如100对应两位小数),转换为整数后比较,避免浮点数直接相等判断的误差。
- 独立记录项数:为每个精度设置单独的计数器,仅在首次达到该精度时记录当前项数。
- 循环终止条件:当最高精度(3.14159)的项数被找到后,终止循环,避免不必要的计算。
- 符合限制条件:未使用
prec、trunc等禁用函数,若需替换llround,可手动实现四舍五入(如(long long)(pi*100 + 0.5))。
内容的提问来源于stack exchange,提问作者Hadiya Kashif
相关产品推荐
相关产品推荐

