前言
This Series aritcles are all based on the book 《经典算法大全》; 对于该书的所有案例进行一个探究和拓展,并且用python和C++进行实现; 目的是熟悉常用算法过程中的技巧和逻辑拓展。
提出问题
17.Algorithm Gossip: 长 PI
为了更精确的求出 PI , 这里的长 PI 法则运用到了一个圆周率公式, 有兴趣的可以研究下, 这里单纯考察的就是模式的应用和推导。
另外为了辅助运算, 可以自行搜索 下sin(23), ln(2) 等数值通过泰拉公式展开的结果进行运算。
评价
送分类型, 无亮点。
分析和解释
代码
C 实现
#include <stdio.h>
#define L 1000
#define N L/4+1
void add(int*, int*, int*);
void sub(int*, int*, int*);
void div(int*, int, int*);
int main(void) {
int s[N+3] = {0};
int w[N+3] = {0};
int v[N+3] = {0};
int q[N+3] = {0};
int n = (int)(L/1.39793 + 1);
int k;
w[0] = 16*5;
v[0] = 4*239;
for(k = 1; k <= n; k++) {
div(w, 25, w);
div(v, 239, v);
div(v, 239, v);
sub(w, v, q);
div(q, 2*k-1, q);
if(k%2)
add(s, q, s);
else
sub(s, q, s);
}
printf("%d.", s[0]);
for(k = 1; k < N; k++)
printf("%04d", s[k]);
printf("
");
return 0;
}
void add(int *a, int *b, int *c) {
int i, carry = 0;
for(i = N+1; i >= 0; i--) {
c[i] = a[i] + b[i] + carry;
if(c[i] < 10000)
carry = 0;
else {
c[i] = c[i] - 10000;
carry = 1;
}
}
}
void sub(int *a, int *b, int *c) {
int i, borrow = 0;
for(i = N+1; i >= 0; i--) {
c[i] = a[i] - b[i] - borrow;
if(c[i] >= 0)
borrow = 0;
else {
c[i] = c[i] + 10000;
borrow = 1;
}
}
}
void div(int *a, int b, int *c) {
int i, tmp, remain = 0;
for(i = 0; i <= N+1; i++) {
tmp = a[i] + remain;
c[i] = tmp / b;
remain = (tmp % b) * 10000;
}
}
拓展和关联
后记
参考书籍
- 《经典算法大全》
- 维基百科