10702
题目
[M5.7**] 输入
解析
马青公式:
结合反正切函数的泰勒级数展开:
答案
c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
long g_base = 10000;
void clear_big_num(long *a, int size) {
for (int i = 0; i < size; i++) {
a[i] = 0;
}
}
void print_big_num(long *a, int n) {
printf("%ld.", a[0]);
for (int i = 1; i <= n / 4; i++) {
printf("%04ld", a[i]);
}
printf("\n");
}
void copy_big_num(long *dest, long *src, int size) {
memcpy(dest, src, size * sizeof(long));
}
void add_big_num(long *a, long *b, long *result, int size) {
long carry = 0;
for (int i = size - 1; i >= 0; i--) {
result[i] = a[i] + b[i] + carry;
if (result[i] >= g_base) {
carry = result[i] / g_base;
result[i] %= g_base;
} else {
carry = 0;
}
}
}
void sub_big_num(long *a, long *b, long *result, int size) {
long borrow = 0;
for (int i = size - 1; i >= 0; i--) {
result[i] = a[i] - b[i] - borrow;
if (result[i] < 0) {
borrow = 1;
result[i] += g_base;
} else {
borrow = 0;
}
}
}
void mul_small_num(long *a, int multiplier, long *result, int size) {
long carry = 0;
for (int i = size - 1; i >= 0; i--) {
long temp = a[i] * multiplier + carry;
result[i] = temp % g_base;
carry = temp / g_base;
}
}
void div_small_num(long *a, int divisor, long *result, int size) {
long remainder = 0;
for (int i = 0; i < size; i++) {
long temp = a[i] + remainder * g_base;
result[i] = temp / divisor;
remainder = temp % divisor;
}
}
void calc_arctan_series(int inverse_x, int size, long *result) {
int inverse_x_sq = inverse_x * inverse_x;
long *term = (long *)malloc(size * sizeof(long));
long *temp_term = (long *)malloc(size * sizeof(long));
clear_big_num(result, size);
clear_big_num(term, size);
term[0] = g_base / inverse_x;
copy_big_num(result, term, size);
for (int k = 3; ; k += 2) {
div_small_num(term, inverse_x_sq, term, size);
copy_big_num(temp_term, term, size);
div_small_num(temp_term, k, temp_term, size);
if ( (k / 2) % 2 == 1 ) {
sub_big_num(result, temp_term, result, size);
} else {
add_big_num(result, temp_term, result, size);
}
int is_zero = 1;
for(int i = 0; i < size; i++) {
if(term[i] != 0) {
is_zero = 0;
break;
}
}
if (is_zero) {
break;
}
}
free(term);
free(temp_term);
}
int main() {
int n;
scanf("%d", &n);
int array_size = n / 4 + 4;
long *pi = (long *)malloc(array_size * sizeof(long));
long *term1 = (long *)malloc(array_size * sizeof(long));
long *term2 = (long *)malloc(array_size * sizeof(long));
long *temp = (long *)malloc(array_size * sizeof(long));
calc_arctan_series(5, array_size, temp);
mul_small_num(temp, 4, term1, array_size);
calc_arctan_series(239, array_size, temp);
mul_small_num(temp, 1, term2, array_size);
sub_big_num(term1, term2, pi, array_size);
mul_small_num(pi, 4, pi, array_size);
print_big_num(pi, n);
free(pi);
free(term1);
free(term2);
free(temp);
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136