2

円周率の公式は、ウィキペディアの記事「円周率の近似」で確認できます。コンパクトで効率的な計算が約束され、10 進法に特化しているため、この式に惹かれました。式は

 pi = -3 + SUM(n=0,oo): n*(2^n)*(n!)^2/(2*n)!

私のCコードは以下です。それは非常に簡単に思えます。すべての中間ステップを計算しますが、完全に収束しません。バグは何ですか?

#include <stdio.h>
#include <math.h>
#define sq(x)  ((x)*(x))
int nfac(int);
int main()
{
  double term, denom, sum;
  double w, x, y, z, pi;
  int n;

/* Plouffe's 1996 algorithm 
(see http://en.wikipedia.org/wiki/Approximations_of_π:  */
  sum = -3.;
  for(n=1; n <= 11; n++)
  {
    printf("n= %d\n", n);
    printf("n! = %.0f\n", w = nfac(n));
    printf("(n!)^2 = %.0f\n", x = sq(w));
    printf("2^n = %.0f\n", y = pow(2,n));
    printf("(2*n)! = %.0f\n", z = nfac(2*n));
    printf("n*2^n)*((n!)^2)/(2*n)! = %f\n", term = n*y*x/z);
    printf("sum = %f\n\n", sum += term);
  }
  printf("pi = %.10f\n\n", pi = sum); 
}

int nfac(int n)
{
  int i, nn;

  if(n==0) return 1;

  nn = 1;
  for(i=1; i<=n; i++)
    nn= i*nn;
  return nn;
}
4

2 に答える 2

2

単純!あなたの- メソッドは...nfacを返しますint

計算中に22 (line: printf("(2*n)! = %.0f\n", z = nfac(2*n));with n = 11) のような引数を付けて呼び出すこともできます。

その結果は;)の中に収まりません。int

には別のタイプを使用することをお勧めしますnfacが、他の人がすでに示唆しているように、 を使用しても結果がどれほど正確になるかわかりませんdouble

于 2013-09-14T17:40:59.170 に答える
0

Adoubleint限られた数しか保持できず、高域に入るとdouble精度が低下します。What Every Computer Scientist Should Know About Floating-Point Arithmeticを本当に読むべきです。

この種の計算を行うには、多数のライブラリが必要です。


例として、64 ビットの符号なし整数を使用するとします。これに適合する最大階乗はいくつですか? 答えはわずか20です!

factorial(21)  = 51090942171709440000
pow(2, 64) - 1 = 18446744073709551615
于 2013-09-14T17:39:12.943 に答える