#define _CRT_SECURE_NO_WARNINGS
#include <string.h>
#include <stdio.h>
#define M 251 // 4*(M-1)=小数点以下の桁数 (10 進)
#define N 209 // 4*(N-1)=小数点以下の桁数 (16 進)
// M-1≒1.204 (N-1)
void Add(unsigned a[], unsigned b[]);
void Sub(unsigned a[], unsigned b[]);
void Div(unsigned a[], unsigned d);
void Mul(unsigned a[], unsigned d);
void Dup(unsigned a[], unsigned b[]);
void ATAN(unsigned x[], int m);
int if_zero(unsigned a[]);
void Display(unsigned a[]);
void to_decimal(unsigned a[], unsigned w[]);
int main(){
unsigned x[N], y[N];
ATAN(x, 5);
Mul(x, 4);
ATAN(y, 239);
Sub(x, y);
Mul(x, 4);
Display(x);
return 0;
}
void ATAN(unsigned x[], int m){
int i, e;
unsigned m2;
unsigned y[N], z[N];
for(i = 0; i < N; i++){ // 配列 x,y の初期化
x[i] = 0;
y[i] = 0;
}
y[0] = 1;
Div(y, m);
Dup(y, x);
m2 = m*m;
i = 1;
do {
Div(y, m2);
Dup(y, z);
Div(z, 2*i+1);
if( (i & 1) == 0 ){ // i が偶数のとき
Add(x, z);
} else { // i が奇数のとき
Sub(x, z);
}
i++;
e = if_zero(z); // z が 0 でないと -1
} while (e == -1); // z が 0 でない限り継続
}
//足算, a + b を a に代入
void Add(unsigned a[], unsigned b[]){
int i,j;
unsigned x;
for(i = 0; i < N; i++){
x = a[i] + b[i];
if(x <= 0xffff){ // 桁上がりしないとき
a[i] = x;
} else { // 桁上がりするとき
a[i] = x & 0xffff; // x の下位 2 バイト
j = i-1; // 以下桁上がりの操作
while(a[j] == 0xffff){ // 1 加えると更に桁が上がるとき
a[j] = 0;
j--;
}
a[j]++;
}
}
}
//引き算, a - b を a に代入 (但し a>b)
void Sub(unsigned a[], unsigned b[]){
int i,j;
for(i = 0; i < N; i++){
if (a[i] >= b[i]){ // そのまま引けるとき
a[i] = a[i] - b[i];
} else { // 上の桁から借りるとき
a[i] = 0x10000 + a[i] - b[i]; // 1 を上から借りる
j = i-1;
while(a[j] == 0){ // 上の桁が 0 であれば
a[j] = 0xffff; // 更に上から借りる
j--;
}
a[j]--;
}
}
}
//割り算, a/d を a に代入 (d <= 0xffff, 16 進 4桁)
// 上の桁から順番に d で割り算。
void Div(unsigned a[], unsigned d){
int i;
unsigned x, q, res;
res = 0;
for(i = 0; i < N; i++){
res = res << 16; // 上の桁の余りを 16 進で4 桁ずらして
x = a[i] + res; // 加える
q = x/d; // d でわる
a[i] = q; // 商
res = x - q*d; // 余りは下の桁の割り算に加える
}
}
//かけ算, a*d を a に代入 (d <= 0xffff, 16 進 4 桁)
// 下の桁から順番に d をかける。
void Mul(unsigned a[], unsigned d){
int i;
unsigned x, q;
q = 0;
for(i = N-1; i >= 0; i--){
x = a[i]*d + q; // 各桁の d 倍に桁上がりの部分を加える
a[i] = x & 0xffff; // x の下位 2 バイト (16 進 4 桁)
q = x >> 16; // x の上位 2 バイト (16 進 4 桁)
} // 桁上がりの部分
}
//a を b にコピー
void Dup(unsigned a[], unsigned b[]){
int i;
for(i = 0; i < N; i++){
b[i] = a[i];
}
}
// a = 0 のとき 0 を返し、そうでないとき -1 を返す関数
int if_zero(unsigned a[]){
int i, j;
j = 0;
for(i = 0; i < N; i++){
if (a[i] != 0) { // 一箇所でも 0 でないとき
j = -1; // j の値を -1 にする
break;
}
}
return j;
}
// 10 進数に変換して表示
void Display(unsigned a[]){
int i,j;
unsigned w[M];
char buf[1000+1] = "";
char tmp[16];
to_decimal(a, w); // 16 進数 a を 10 進数 w に変換
for(i = 1; i < M; i++){
sprintf(tmp
, "%4.4u", w
[i
]);// 4 桁ごとバッファに格納 }
printf("%4.1u.",w
[0]); // 小数点以上の表示 for(i = 0; i < 1000/5; i++){
printf("%.5s ", buf
+i
*5); // 5 桁ごと表示 j = i%10; // j は i を 10 で割った余り
if(j
==10-1) printf("\n "); // 10 個表示したとき改行 }
}
// 10 進数への変換
void to_decimal(unsigned a[], unsigned w[]){
int i;
unsigned b[N];
for(i = 0; i < N; i++){
b[i] = a[i];
}
w[0] = b[0];
b[0] = 0;
for(i = 1; i < M; i++){
Mul(b, 10000); // b を 10000 倍して
w[i] = b[0]; // 小数点以上を w[i] に代入
b[0] = 0; // 小数点以上を 0 にする
}
}
I2RlZmluZSBfQ1JUX1NFQ1VSRV9OT19XQVJOSU5HUwojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxzdGRpby5oPgoKI2RlZmluZSBNIDI1MSAgIC8vIDQqKE0tMSk95bCP5pWw54K55Lul5LiL44Gu5qGB5pWwICgxMCDpgLIpCiNkZWZpbmUgTiAyMDkgICAvLyA0KihOLTEpPeWwj+aVsOeCueS7peS4i+OBruahgeaVsCAoMTYg6YCyKQogICAgICAgICAgICAgICAgLy8gTS0x4omSMS4yMDQgKE4tMSkKCnZvaWQgQWRkKHVuc2lnbmVkIGFbXSwgdW5zaWduZWQgYltdKTsKdm9pZCBTdWIodW5zaWduZWQgYVtdLCB1bnNpZ25lZCBiW10pOwp2b2lkIERpdih1bnNpZ25lZCBhW10sIHVuc2lnbmVkIGQpOwp2b2lkIE11bCh1bnNpZ25lZCBhW10sIHVuc2lnbmVkIGQpOwp2b2lkIER1cCh1bnNpZ25lZCBhW10sIHVuc2lnbmVkIGJbXSk7CnZvaWQgQVRBTih1bnNpZ25lZCB4W10sIGludCBtKTsKaW50IGlmX3plcm8odW5zaWduZWQgYVtdKTsKdm9pZCBEaXNwbGF5KHVuc2lnbmVkIGFbXSk7CnZvaWQgdG9fZGVjaW1hbCh1bnNpZ25lZCBhW10sIHVuc2lnbmVkIHdbXSk7CgoKCmludCBtYWluKCl7CiAgICB1bnNpZ25lZCB4W05dLCB5W05dOwoKICAgIEFUQU4oeCwgNSk7CiAgICBNdWwoeCwgNCk7CgogICAgQVRBTih5LCAyMzkpOwoKICAgIFN1Yih4LCB5KTsKICAgIE11bCh4LCA0KTsKCiAgICBEaXNwbGF5KHgpOwogICAgcmV0dXJuIDA7Cn0KCnZvaWQgQVRBTih1bnNpZ25lZCB4W10sIGludCBtKXsKICAgIGludCBpLCBlOwogICAgdW5zaWduZWQgbTI7CiAgICB1bnNpZ25lZCB5W05dLCB6W05dOwogICAgZm9yKGkgPSAwOyBpIDwgTjsgaSsrKXsgICAgIC8vIOmFjeWIlyB4LHkg44Gu5Yid5pyf5YyWCiAgICAgICAgeFtpXSA9IDA7CiAgICAgICAgeVtpXSA9IDA7CiAgICB9CiAgICB5WzBdID0gMTsKCiAgICBEaXYoeSwgbSk7CiAgICBEdXAoeSwgeCk7CiAgICBtMiA9IG0qbTsKICAgIGkgPSAxOwogICAgZG8gewogICAgICAgIERpdih5LCBtMik7CiAgICAgICAgRHVwKHksIHopOwogICAgICAgIERpdih6LCAyKmkrMSk7CiAgICAgICAgaWYoIChpICYgMSkgPT0gMCApeyAgICAgLy8gaSDjgYzlgbbmlbDjga7jgajjgY0KICAgICAgICAgICAgQWRkKHgsIHopOwogICAgICAgIH0gZWxzZSB7ICAgICAgICAgICAgICAgIC8vIGkg44GM5aWH5pWw44Gu44Go44GNCiAgICAgICAgICAgIFN1Yih4LCB6KTsKICAgICAgICB9CiAgICAgICAgaSsrOwogICAgICAgIGUgPSBpZl96ZXJvKHopOyAgICAgICAgIC8vIHog44GMIDAg44Gn44Gq44GE44GoIC0xCiAgICB9IHdoaWxlIChlID09IC0xKTsgICAgICAgICAgLy8geiDjgYwgMCDjgafjgarjgYTpmZDjgorntpnntpoKICAgIAp9CgovL+i2s+eulywgIGEgKyBiIOOCkiBhIOOBq+S7o+WFpQp2b2lkIEFkZCh1bnNpZ25lZCBhW10sIHVuc2lnbmVkIGJbXSl7CiAgICBpbnQgaSxqOwogICAgdW5zaWduZWQgeDsKICAgIGZvcihpID0gMDsgaSA8IE47IGkrKyl7CiAgICAgICAgeCA9IGFbaV0gKyBiW2ldOwogICAgICAgIGlmKHggPD0gMHhmZmZmKXsgICAgICAgICAgICAvLyDmoYHkuIrjgYzjgorjgZfjgarjgYTjgajjgY0KICAgICAgICAgICAgYVtpXSA9IHg7CiAgICAgICAgfSBlbHNlIHsgICAgICAgICAgICAgICAgICAgIC8vIOahgeS4iuOBjOOCiuOBmeOCi+OBqOOBjQogICAgICAgICAgICBhW2ldID0geCAmIDB4ZmZmZjsgICAgICAvLyB4IOOBruS4i+S9jSAyIOODkOOCpOODiAogICAgICAgICAgICBqID0gaS0xOyAgICAgICAgICAgICAgICAvLyDku6XkuIvmoYHkuIrjgYzjgorjga7mk43kvZwKICAgICAgICAgICAgd2hpbGUoYVtqXSA9PSAweGZmZmYpeyAgLy8gMSDliqDjgYjjgovjgajmm7TjgavmoYHjgYzkuIrjgYzjgovjgajjgY0KICAgICAgICAgICAgICAgIGFbal0gPSAwOwogICAgICAgICAgICAgICAgai0tOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGFbal0rKzsKICAgICAgICB9CiAgICB9Cn0KCi8v5byV44GN566XLCAgYSAtIGIg44KSIGEgIOOBq+S7o+WFpSAo5L2G44GXIGE+YikKdm9pZCBTdWIodW5zaWduZWQgYVtdLCB1bnNpZ25lZCBiW10pewogICAgaW50IGksajsKICAgIGZvcihpID0gMDsgaSA8IE47IGkrKyl7CiAgICAgICAgaWYgKGFbaV0gPj0gYltpXSl7ICAgICAgICAgICAgICAgICAgLy8g44Gd44Gu44G+44G+5byV44GR44KL44Go44GNCiAgICAgICAgICAgIGFbaV0gPSBhW2ldIC0gYltpXTsKICAgICAgICB9IGVsc2UgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyDkuIrjga7moYHjgYvjgonlgJ/jgorjgovjgajjgY0KICAgICAgICAgICAgYVtpXSA9IDB4MTAwMDAgKyBhW2ldIC0gYltpXTsgICAvLyAxIOOCkuS4iuOBi+OCieWAn+OCiuOCiwogICAgICAgICAgICBqID0gaS0xOwogICAgICAgICAgICB3aGlsZShhW2pdID09IDApeyAgICAgICAgICAgICAgIC8vIOS4iuOBruahgeOBjCAwIOOBp+OBguOCjOOBsAogICAgICAgICAgICAgICAgYVtqXSA9IDB4ZmZmZjsgICAgICAgICAgICAgIC8vIOabtOOBq+S4iuOBi+OCieWAn+OCiuOCiwogICAgICAgICAgICAgICAgai0tOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGFbal0tLTsKICAgICAgICB9CiAgICB9Cgp9CgovL+WJsuOCiueulywgIGEvZCDjgpIgYSDjgavku6PlhaUgKGQgPD0gMHhmZmZmLCAxNiDpgLIgNOahgSkKLy8g5LiK44Gu5qGB44GL44KJ6aCG55Wq44GrIGQg44Gn5Ymy44KK566X44CCCnZvaWQgRGl2KHVuc2lnbmVkIGFbXSwgdW5zaWduZWQgZCl7CiAgICBpbnQgaTsKICAgIHVuc2lnbmVkIHgsIHEsIHJlczsKICAgIHJlcyA9IDA7CiAgICBmb3IoaSA9IDA7IGkgPCBOOyBpKyspewogICAgICAgIHJlcyA9IHJlcyA8PCAxNjsgICAgICAgIC8vIOS4iuOBruahgeOBruS9meOCiuOCkiAxNiDpgLLjgac0IOahgeOBmuOCieOBl+OBpgogICAgICAgIHggPSBhW2ldICsgcmVzOyAgICAgICAgIC8vIOWKoOOBiOOCiwogICAgICAgIHEgPSB4L2Q7ICAgICAgICAgICAgICAgIC8vIGQg44Gn44KP44KLCiAgICAgICAgYVtpXSA9IHE7ICAgICAgICAgICAgICAgLy8g5ZWGCiAgICAgICAgcmVzID0geCAtIHEqZDsgICAgICAgICAgLy8g5L2Z44KK44Gv5LiL44Gu5qGB44Gu5Ymy44KK566X44Gr5Yqg44GI44KLCiAgICB9Cn0KCi8v44GL44GR566XLCBhKmQg44KSIGEg44Gr5Luj5YWlIChkIDw9IDB4ZmZmZiwgMTYg6YCyIDQg5qGBKQovLyDkuIvjga7moYHjgYvjgonpoIbnlarjgasgZCDjgpLjgYvjgZHjgovjgIIKdm9pZCBNdWwodW5zaWduZWQgYVtdLCB1bnNpZ25lZCBkKXsKICAgIGludCBpOyAKICAgIHVuc2lnbmVkIHgsIHE7CiAgICBxID0gMDsKICAgIGZvcihpID0gTi0xOyBpID49IDA7IGktLSl7CiAgICAgICAgeCA9IGFbaV0qZCArIHE7ICAgICAgICAgLy8g5ZCE5qGB44GuIGQg5YCN44Gr5qGB5LiK44GM44KK44Gu6YOo5YiG44KS5Yqg44GI44KLCiAgICAgICAgYVtpXSA9IHggJiAweGZmZmY7ICAgICAgLy8geCDjga7kuIvkvY0gMiDjg5DjgqTjg4ggKDE2IOmAsiA0IOahgSkKICAgICAgICBxID0geCA+PiAxNjsgICAgICAgICAgICAvLyB4IOOBruS4iuS9jSAyIOODkOOCpOODiCAoMTYg6YCyIDQg5qGBKQogICAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIOahgeS4iuOBjOOCiuOBrumDqOWIhgp9CgovL2Eg44KSIGIg44Gr44Kz44OU44O8CnZvaWQgRHVwKHVuc2lnbmVkIGFbXSwgdW5zaWduZWQgYltdKXsKICAgIGludCBpOwogICAgZm9yKGkgPSAwOyBpIDwgTjsgaSsrKXsKICAgICAgICBiW2ldID0gYVtpXTsKICAgIH0KfQoKLy8gYSA9IDAg44Gu44Go44GNIDAg44KS6L+U44GX44CB44Gd44GG44Gn44Gq44GE44Go44GNIC0xIOOCkui/lOOBmemWouaVsAppbnQgaWZfemVybyh1bnNpZ25lZCBhW10pewogICAgaW50IGksIGo7CiAgICBqID0gMDsKICAgIGZvcihpID0gMDsgaSA8IE47IGkrKyl7CiAgICAgICAgaWYgKGFbaV0gIT0gMCkgeyAgICAgICAgICAgIC8vIOS4gOeuh+aJgOOBp+OCgiAwIOOBp+OBquOBhOOBqOOBjQogICAgICAgICAgICBqID0gLTE7ICAgICAgICAgICAgICAgICAvLyBqIOOBruWApOOCkiAtMSDjgavjgZnjgosKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIGo7Cn0KCi8vICAxMCDpgLLmlbDjgavlpInmj5vjgZfjgabooajnpLoKdm9pZCBEaXNwbGF5KHVuc2lnbmVkIGFbXSl7CiAgICBpbnQgaSxqOwogICAgdW5zaWduZWQgd1tNXTsKICAgIGNoYXIgYnVmWzEwMDArMV0gPSAiIjsKICAgIGNoYXIgdG1wWzE2XTsKICAgIHRvX2RlY2ltYWwoYSwgdyk7ICAgICAgICAgICAgICAgLy8gMTYg6YCy5pWwIGEg44KSIDEwIOmAsuaVsCB3IOOBq+WkieaPmwogICAgZm9yKGkgPSAxOyBpIDwgTTsgaSsrKXsKICAgICAgICBzcHJpbnRmKHRtcCwgIiU0LjR1Iiwgd1tpXSk7Ly8gNCDmoYHjgZTjgajjg5Djg4Pjg5XjgqHjgavmoLzntI0KICAgICAgICBzdHJjYXQoYnVmLCB0bXApOwogICAgfQogICAgcHJpbnRmKCIlNC4xdS4iLHdbMF0pOyAgICAgICAgICAvLyDlsI/mlbDngrnku6XkuIrjga7ooajnpLoKICAgIGZvcihpID0gMDsgaSA8IDEwMDAvNTsgaSsrKXsKICAgICAgICBwcmludGYoIiUuNXMgIiwgYnVmK2kqNSk7ICAgLy8gNSDmoYHjgZTjgajooajnpLoKICAgICAgICBqID0gaSUxMDsgICAgICAgICAgICAgICAgICAgLy8gaiDjga8gaSDjgpIgMTAg44Gn5Ymy44Gj44Gf5L2Z44KKCiAgICAgICAgaWYoaj09MTAtMSkgcHJpbnRmKCJcbiAgICAgIik7IC8vIDEwIOWAi+ihqOekuuOBl+OBn+OBqOOBjeaUueihjAogICAgfQogICAgcHJpbnRmKCJcbiIpOyAgICAgICAgICAgICAgICAgICAvLyDkuIDnlarmnIDlvozjgavmlLnooYwKfQoKLy8gIDEwIOmAsuaVsOOBuOOBruWkieaPmwp2b2lkIHRvX2RlY2ltYWwodW5zaWduZWQgYVtdLCB1bnNpZ25lZCB3W10pewogICAgaW50IGk7CiAgICB1bnNpZ25lZCBiW05dOwogICAgZm9yKGkgPSAwOyBpIDwgTjsgaSsrKXsKICAgICAgICBiW2ldID0gYVtpXTsKICAgIH0KICAgIHdbMF0gPSBiWzBdOwogICAgYlswXSA9IDA7CiAgICBmb3IoaSA9IDE7IGkgPCBNOyBpKyspewogICAgICAgIE11bChiLCAxMDAwMCk7ICAgICAgICAgICAgICAvLyBiIOOCkiAxMDAwMCDlgI3jgZfjgaYKICAgICAgICB3W2ldID0gYlswXTsgICAgICAgICAgICAgICAgLy8g5bCP5pWw54K55Lul5LiK44KSIHdbaV0g44Gr5Luj5YWlCiAgICAgICAgYlswXSA9IDA7ICAgICAgICAgICAgICAgICAgIC8vIOWwj+aVsOeCueS7peS4iuOCkiAwIOOBq+OBmeOCiwogICAgfQp9Cg==