₃₀C₂₁(1/2)²¹(1/2)⁹ + ₃₀C₂₂(1/2)²²(1/2)⁸ + ... + ₃₀C₂₉(1/2)²⁹(1/2)¹ + ₃₀C₃₀(1/2)³⁰
を計算する問題(ではないけど)があったので、コンピュータにやらせちゃおうと思いました。
main.c
#include <stdio.h>
#include <stdlib.h>
void bunsu_tasizan(long,long,long,long,long*,long*);
void yakubun(long*,long*);
void C_keisan(long,long,long*,long*);
long yukurido(long, long);
int main() {
long double shousu;
int x = 30,y = 21;
int kou_size = x - y + 1;
long bunsi;
long bunbo;
long *kakubunsi = (long*)malloc(sizeof(long) * kou_size);
long *kakubunbo = (long*)malloc(sizeof(long) * kou_size);
long kekka_bunsi;
long kekka_bunbo;
long ni_sanjujou = 1;
int i;
for(i = 0;i < 30;i++){
ni_sanjujou *= 2;
}
for(i = 0;i < (kou_size);i++){
C_keisan(x,y + i,&bunsi,&bunbo);
kakubunsi[i] = bunsi;
kakubunbo[i] = bunbo * ni_sanjujou;
}
kekka_bunsi = kakubunsi[0];
kekka_bunbo = kakubunbo[0];
for(i = 0;i < (x - y);i++){
bunsu_tasizan(kekka_bunsi,kekka_bunbo,kakubunsi[i+1],kakubunbo[i+1],&kekka_bunsi,&kekka_bunbo);
}
printf("%ld/%ld\n",kekka_bunsi,kekka_bunbo);
shousu = (long double)kekka_bunsi / (long double)kekka_bunbo;
printf("%.15Lf\n",shousu);
free(kakubunsi);
free(kakubunbo);
return 0;
}
void bunsu_tasizan(long bunsi1,long bunbo1,long bunsi2,long bunbo2,long *bunsi,long *bunbo){
if(bunbo1 != bunbo2){
long a;
a = yukurido(bunbo1,bunbo2);
long tsubun_bunbo = bunbo1 / a;
bunbo1 *= (bunbo2 / a);
bunsi1 *= (bunbo2 / a);
bunsi2 *= (tsubun_bunbo);
}
(*bunbo) = bunbo1;
(*bunsi) = bunsi1 + bunsi2;
yakubun(bunsi,bunbo);
}
void C_keisan(long n,long m,long *bunsi,long *bunbo){
long bunsi2 = 1;
long bunbo2 = 1;
if(n - m < m){
m = n - m;
}
int kou_size = m;
long *bunsi1 = (long*)malloc(sizeof(long)*kou_size);
long *bunbo1 = (long*)malloc(sizeof(long)*kou_size);
for (int i = 0;i < m;i++){
bunsi1[i] = (n - i);
bunbo1[i] = (m - i);
}
for(int i = 0;i < m;i++){
for(int j = 0;j<m;j++){
if(*(bunsi+i) == 1){
j = m;
}
else{
yakubun(bunsi1+i,bunbo1+j);
}
}
}
for(int i = 0;i < m;i++){
bunsi2 *= *(bunsi1+i);
bunbo2 *= *(bunbo1+i);
}
free(bunsi1);
free(bunbo1);
yakubun(&bunsi2,&bunbo2);
(*bunsi) = bunsi2;
(*bunbo) = bunbo2;
}
void yakubun(long *bunsi,long *bunbo){
long maxkouyakusu;
maxkouyakusu = yukurido(*bunsi,*bunbo);
(*bunsi) /= maxkouyakusu;
(*bunbo) /= maxkouyakusu;
}
long yukurido(long x,long y){
long temp;
if(x < y){
temp = x;
x = y;
y = temp;
}
long r = x % y;
while(r != 0){
x = y;
y = r;
r = x % y;
}
return y;
}
実行結果
22964087/1073741824
0.021386972628534
無駄な部分がめちゃくちゃ多いと思うけど、修正するの大変なので許してください。
今回コードを書いてみて、C言語のポインタの便利さがめっちゃわかりました。