fork download
  1. #include <stdio.h>
  2.  
  3. #define M 8 // 4*(M-1)=小数点以下の桁数 (10 進表示)
  4. #define N 7 // 4*(N-1)=小数点以下の桁数 (16 進表示)
  5. // M-1≒1.204(N-1) (M, N の関係)
  6.  
  7. void Add(unsigned a[], unsigned b[]);
  8. void Sub(unsigned a[], unsigned b[]);
  9. void Div(unsigned a[], unsigned d);
  10. void Mul(unsigned a[], unsigned d);
  11. void Dup(unsigned a[], unsigned b[]);
  12. void ATAN(unsigned x[], int m);
  13. int if_zero(unsigned a[]);
  14. void Display(unsigned a[]);
  15. void to_decimal(unsigned a[], unsigned w[]);
  16.  
  17. void main(){
  18. unsigned x[N];
  19.  
  20. ATAN(x, 5);
  21. Display(x);
  22. }
  23. // arctan(1/m) を x に格納
  24.  
  25. void ATAN(unsigned x[], int m){
  26. int i, e;
  27. unsigned m2;
  28. unsigned y[N], z[N];
  29. for(i = 0; i < N; i++){ // 配列 x,y の初期化
  30. x[i] = 0;
  31. y[i] = 0;
  32. }
  33. y[0] = 1;
  34.  
  35. Div(y, m);
  36. Dup(y, x);
  37. m2 = m*m;
  38. i = 1;
  39. do {
  40. Div(y, m2);
  41. Dup(y, z);
  42. Div(z, 2*i+1);
  43. if( (i & 1) == 0 ){ // i が偶数のとき
  44. Add(x, z);
  45. } else { // i が奇数のとき
  46. Sub(x, z);
  47. }
  48. i++;
  49. e = if_zero(z); // z が 0 でないと -1
  50. } while (e == -1); // z が 0 でない限り継続
  51.  
  52. }
  53.  
  54. //足算, a + b を a に代入
  55. void Add(unsigned a[], unsigned b[]){
  56. int i,j;
  57. unsigned x;
  58. for(i = 0; i < N; i++){
  59. x = a[i] + b[i];
  60. if(x <= 0xffff){ // 桁上がりしないとき
  61. a[i] = x;
  62. } else { // 桁上がりするとき
  63. a[i] = x & 0xffff; // x の下位 2 バイト
  64. j = i-1; // 以下桁上がりの操作
  65. while(a[j] == 0xffff){ // 1 加えると更に桁が上がるとき
  66. a[j] = 0;
  67. j--;
  68. }
  69. a[j]++;
  70. }
  71. }
  72. }
  73.  
  74. //引き算, a - b を a に代入 (但し a>b)
  75. void Sub(unsigned a[], unsigned b[]){
  76. int i,j;
  77. for(i = 0; i < N; i++){
  78. if (a[i] >= b[i]){ // そのまま引けるとき
  79. a[i] = a[i] - b[i];
  80. } else { // 上の桁から借りるとき
  81. a[i] = 0x10000 + a[i] - b[i]; // 1 を上から借りる
  82. j = i-1;
  83. while(a[j] == 0){ // 上の桁が 0 であれば
  84. a[j] = 0xffff; // 更に上から借りる
  85. j--;
  86. }
  87. a[j]--;
  88. }
  89. }
  90. }
  91.  
  92. //割り算, a/d を a に代入 (d <= 0xffff, 16 進 4桁)
  93. // 上の桁から順番に d で割り算。
  94. void Div(unsigned a[], unsigned d){
  95. int i;
  96. unsigned x, q, res;
  97. res = 0;
  98. for(i = 0; i < N; i++){
  99. res = res << 16; // 上の桁の余りを 16 進で4 桁ずらして
  100. x = a[i] + res; // 加える
  101. q = x/d; // d でわる
  102. a[i] = q; // 商
  103. res = x - q*d; // 余りは下の桁の割り算に加える
  104. }
  105. }
  106.  
  107. //かけ算, a*d を a に代入 (d <= 0xffff, 16 進 4 桁)
  108. // 下の桁から順番に d をかける。
  109. void Mul(unsigned a[], unsigned d){
  110. int i;
  111. unsigned x, q;
  112. q = 0;
  113. for(i = N-1; i >= 0; i--){
  114. x = a[i]*d + q; // 各桁の d 倍に桁上がりの部分を加える
  115. a[i] = x & 0xffff; // x の下位 2 バイト (16 進 4 桁)
  116. q = x >> 16; // x の上位 2 バイト (16 進 4 桁)
  117. } // 桁上がりの部分
  118. }
  119.  
  120. //a を b にコピー
  121. void Dup(unsigned a[], unsigned b[]){
  122. int i;
  123. for(i = 0; i < N; i++){
  124. b[i] = a[i];
  125. }
  126. }
  127.  
  128. // a = 0 のとき 0 を返し、そうでないとき -1 を返す関数
  129. int if_zero(unsigned a[]){
  130. int i, j;
  131. j = 0;
  132. for(i = 0; i < N; i++){
  133. if (a[i] != 0) { // 一箇所でも 0 でないとき
  134. j = -1; // j の値を -1 にする
  135. break;
  136. }
  137. }
  138. return j;
  139. }
  140.  
  141. // 10 進数に変換して表示
  142. void Display(unsigned a[]){
  143. int i,j;
  144. unsigned w[M];
  145. to_decimal(a, w); // 16 進数 a を 10 進数 w に変換
  146. printf("%4.1u.",w[0]); // 小数点以上の表示
  147. for(i = 1; i < M; i++){
  148. switch(i%5){
  149. case 1: printf("%4.4u", w[i]); // 4 桁ごと表示
  150. break;
  151. case 2:printf("%1.1u %3.3u", w[i]/1000, w[i]%1000); // 4 桁ごと表示
  152. break;
  153. case 3:printf("%2.2u", w[i]/100); // 4 桁ごと表示
  154. if(i%25==13) printf("\n "); // 10 個表示したとき改行
  155. else printf(" ");
  156. printf("%2.2u", w[i]%100); // 4 桁ごと表示
  157. break;
  158. case 4:printf("%3.3u %1.1u", w[i]/10, w[i]%10); // 4 桁ごと表示
  159. break;
  160. case 0:printf("%4.4u", w[i]); // 4 桁ごと表示
  161. if(i%25==0) printf("\n "); // 10 個表示したとき改行
  162. else printf(" "); break;
  163. }
  164. }
  165. }
  166.  
  167. // 10 進数への変換
  168. void to_decimal(unsigned a[], unsigned w[]){
  169. int i;
  170. unsigned b[N];
  171. for(i = 0; i < N; i++){
  172. b[i] = a[i];
  173. }
  174. w[0] = b[0];
  175. b[0] = 0;
  176. for(i = 1; i < M; i++){
  177. Mul(b, 10000); // b を 10000 倍して
  178. w[i] = b[0]; // 小数点以上を w[i] に代入
  179. b[0] = 0; // 小数点以上を 0 にする
  180. }
  181. }
Runtime error #stdin #stdout 0.02s 1676KB
stdin
Standard input is empty
stdout
   0.19739 55598 49880 75837 00497 652