int main(void) { long a=10000;// 缩放系数 long c=2800; // 迭代次数 long f[2801];// 中间计算结果 long d; // 内循环误差累计项 long e=0; // 外循环误差累计项 long b, g; // 分子 与 分母. k/(2k+1) int i, j;
for(i=0; i<c; i++) // 若完全依照公式,循环条件应为“for(i=1; i<=c; i++)”。幸好f[2800]的贡献非常小,取任意值都不会对精度造成太大的影响 f[i] = 2 * a/10; // 2就是公式中的系数2。 a/10的意思是保留一个十进制位,因为输出是从个位3开始的 while(c > 0) { d = 0; g = (c*2 + 1) - 2; // 分母。因为每次循环都输出了4位,所以在后面运算时乘以了a,所以这里得 -2 b = c; // 分子 while(b > 0) { /* 根据公式,乘以分子 */ d *= b; d += f[b]*a; // 因为每次外循环都输出了4位 /* 根据公式,除以分母 */ f[b] = d % g; // 带分数的 分子部分 d /= g; // 带分数的 整数部分 /* Next */ g -= 2; b--; } printf("%.4d", e+d/a); e = d % a; c -= 14; // 因为精度固定为800位,每输出4位后,相当于精度需求降低了4位,所以每次可以少算14项 } printf("/n"); return 0; }