• 締切済み

この計算プログラムの書き方を教えてください.

C++で,次の式の計算プログラムを書きたいのですが,今ひとつ(というか全く)分かりせん. どなたか,教えていただけないでしょうか.できたら,ソースを書いていただけると嬉しいです... P0 = (Σ(n=0からc-1まで)a^{n}/n! + a^{c}/((c-1)!(c-a)))^{-1} です. cの値を0から100まで変化させたときの,P0の値を求めたいので,for文つかって,あとは結果を加算してったいらいいんでしょうが,階乗が入ってきてしまい,全く分からなくなってしまいました... ちなみに,aは定数なので,そのままで構わないと思います. プログラマの方,よろしくお願いしたします.

みんなの回答

  • net-in
  • ベストアンサー率12% (1/8)
回答No.3

べき乗は <math.h> のなかに pow( x, y ) : xのy乗 があったと思いますよん

全文を見る
すると、全ての回答が全文表示されます。
回答No.2

大切なことから書きます。 式の中にとてつもなく大きな数値になるものが含まれていますよね。例えば、99!とか、(aがいくつなのかによりますけど) a^100とか。 C/C++の整数型の変数だけではまかないきれません。 浮動小数点を使用したら何とかなりますが、今度は桁落ちなどを考慮する必要があります。果たしてあなたの期待している精度が保てるかどうか... 以上を無視して、単純に論理部分だけ書くと以下のように作る方法があります。 (1)階乗を計算する関数を用意する。 double fact(int x); *中身はご自身で考えてくださいね。 (2)べき乗を計算する関数を用意する。 double pow(int x, int y); *中身はご自身で考えてくださいね。 (3)本体 const int a = 10; // 定数aです。 for(int c=1; c<=100; c++) {    double p = 0;    // シグマの計算  for(int n=0; n<c; n++) {      p = pow(a, n)/fact(n) + pow(a, c)/(fact(c-1)*(c-a));  }  // その逆数がcを与えたときのP0  printf("P0(C=%d) = %f\n", 1/p); } 参考まで。

starground
質問者

お礼

ありがとうございました. なんとかできました. ですね,確かに階乗計算で100!ってのは ありえないですよね(汗). なので,とりあえず10!ぐらいまでにして おきました. 本当にたすかりました. これからも何かありましたら,アドバイスよ ろしくお願いいたします.

全文を見る
すると、全ての回答が全文表示されます。
  • yomo3
  • ベストアンサー率32% (88/269)
回答No.1

すぐに回答が欲しいと言うことなので、とりあえず。 コードを全て核余裕がないので、階乗部分のヒントだけで許してください。 適当な変数(nkaiとか)にforループの外側で1を代入。 forループの最初に nkai=nkai*n; という行を入れる。 この値がn!になります。

starground
質問者

お礼

ありがとうございます. なんとなく分かるのですが,これを実装するとなるとまだよく分かりません...すみません... コードを書いていただけるなら時間が多少かかっても大丈夫なので,細かく教えていただけないでしょうか?

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • 階乗のプログラム

    c言語初心者です。 13までの階乗の値を計算するプログラムを下のように書いたのですが、 #include <stdio.h> main() { int N, fact; fact=1; for(N=1; N<=13; ++N){ fact=fact*N; printf("%d!=%d\n",N, fact); } } このプログラムを実行してみると、12!までは正しい値が出力されるのですが、13!の値が1932053504と出力され、計算機の値と違います。 どこが間違っているのでしょうか。どなたかご教授お願いします。

  • Σ[n=0..∞](A^4n)/((n!)^2*(2n!))の和は?

    Σ[n=0..∞](A^4n)/((n!)^2*((2n)!))の和は? Σ[n=0..∞](A^4n)/((n!)^2*((2n)!))の和が分かりません。。。 マクローリン展開かと思ったのですが、階乗同士の掛け算があったりで、混乱しています。ちなみに、Aは定数で、ある値が入ると考えていただいて結構です。 よろしくお願いいたします!

  • 桁あふれ誤差のプログラムで質問です。

    1から15までの階乗を計算するプログラムで、階乗を求める関数を定義してその結果を確認し、その際に階乗の計算を開始する数と終了する数を記号定数で定義(#defineを使って)したいのですが、分からなくて困っています。 関数を使わないで以下のようにやり、 #include <stdio.h> #include <math.h> int main(void) { int n; int ans=1; for(n=1;n<=15;n++) { ans=ans*n; printf("%d!=%d\n",n,ans); } return 0; } これをやってみてなんとか結果が確認できたのですが、上記のように、階乗を求める関数を定義して、この上記のプログラムを書き換えて、そのときに階乗の計算を開始する数と終了する数を記号定数で定義(#defineを使って)して行いたいのですが、 分からなくて本当に困っています。助けてください。

  • プログラムについて(C言語)

    #include<stdio.h> int main() { int i,n,total; for(;;){ /* 無限ループ*/ printf("整数n?"); /* nの値の表示 */ scanf("%d",&n); /* ifとbreakを使った終了判定 */ if(n<0)break; total=1; for(i=1;i<=n;i++){ printf("i=%d ",i); total*=i; /* total←total*i(階乗の計算) */ } printf("total=%d\n",total); /* totalの値(結果)の表示 */ } printf("Thanks\n"); /* 終了メッセージの表示 */ return(0); } これは階乗を求めるプログラムなのですが、i++ではなくi--をつかって求める場合 どのように変更すればよいでしょうか? for(i=1;i<=n;i++){ あたりをいろいろ弄ってみたのですが、求めてる結果は得られませんでした

  • C言語の質問

    「n の階乗 n! の計算を再帰式で表現したCプログラムを作成し、n=10, n=11, n=12 の出力結果を書きなさい。 プログラムではnの値は1から12までとせよ。 入出力については問わない。」です。お願いします。

  • C言語の、階乗を使うプログラムの問題を教えて下さい

    C言語の、このプログラムを作るのが分かる方、教えて下さい。階乗を使う問題です。 「キーボードで整数aを入力するとn!>aとなるときの最小のnを出力するプログラムを作りなさい」という問題です。 分からず苦戦しています。 nをキーボードで入力してn!を求めるには #include<stdio.h> int main(void) { int kekka,n,i; printf("n=? \n"); scanf("%d",&n); kekka=1; for(i=1;i<=n;i++) { kekka=kekka*i; } printf("%d!は%dです。\n",n,kekka); return 0; } とすればいいのは自分で作れたのですが、問題にあるn!>aのプログラムが分からず困っています。 分かる方、お願いいたします

  • ガウスの掃き出し法によるC++プログラム

    大学で、ガウスーヨルダンの掃き出し法により連立方程式を解き、係数マトリクスの逆行列と解を表示するプログラムを作れ、という課題が出ました。 4s+t+3u+2v=23 s+4t+3u+3v=30 5s+5t+10u+5v=65 4s+4t+2u+6v=42 という問題です。 まったく素人の状態から4時間ほどやったくらいでこの問題が出たので、解き方が全くわからなかったのですが、いろいろなサイトを巡ってこのようなプログラムを作りました。 #include <stdio.h> #include <float.h> #define N 4 /* 行列の行数および列数 */ double A[N][N] = { { 4.0,1.0,3.0,2.0}, /* 係数行列 A の定義 */ {1.0,4.0,3.0,3.0}, {5.0,5.0,10.0,5.0}, {4.0,4.0,2.0,6.0}}; double b[N] = {23.0,30.0,65.0,42.0}; /* 定数ベクトル b の定義 */ void Gauss_J( int, double*, double* ); void main( void ) { int i; /* カウンタ */ printf( "%d元連立一次方程式\n", N ); for( i = 0; i < N ; i++ ) { printf( "%g s + %g t + %g u + %g v = %g \n", A[i][0], A[i][1], A[i][2],A[i][3], b[i] ); } printf("の解は,\n" ); Gauss_J( N, (double *)A, (double *)b ); /* ガウス・ジョルダン法で解く */ printf( "s = %g \n", b[0] ); printf( "t = %g \n", b[1] ); printf( "u = %g \n", b[2] ); printf( "v = %g \n", b[3] ); } void Gauss_J( int n, double *a, double *b ) { int p, i, j, l ; /* カウンタ */ double pivot, c ; /* ピボット値 */ for ( p = 0 ; p < n ; p++ ) /* 1行目から n行目まで繰り返す */ { pivot = a[ p*n + p ]; /* ピボットを取得する */ for ( i = p ; i < n ; i++ ) /* p行目の p列目から n列目まで */ { a[ p*n + i ] /= pivot; /* 係数行列の p行を pivotで割る */ } b[ p ] /= pivot; /* 定数ベクトルの p行を pivotで割る */ for ( l = 0 ; l < n ; l++ ) /* 1行目から n行目まで */ { if ( l != p ) /* p行を除いて */ { c = a[ l*n + p ]; /* 掃き出す */ for ( j = p ; j < n ; j++ ) { a[ l*n + j ] -= c * a[ p*n + j ]; } b[ l ] -= c * b[ p ]; } } } return ; } これで行列の解は出るようになったのですが、逆行列が表示されてません。 どうすれば表示されるようになるのでしょうか?

  • パソコンで階乗を計算

    現在、fortran90を使って階乗を計算するプログラムを作っております。 プログラム内容は、(n !を求めえるプログラム) n=0 do i=1,100 n=n*i enddo このプログラムを実行すると、12!までは予想された値が得られるのですが、13!以降は電卓で計算した値と遙かに異なる値が得られました。 このプログラムは間違っているとは思えないですが、電卓の計算とパソコンの計算が異なる結果になった理由が分かりません。 どなたか、ヒントや参考情報だけでもいいので教えてください。 ちなみにパソコンによる計算結果は、 i n 1 1 2 2 3 6 4 24 5 120 6 720 7 5040 8 40320 9 362880 10 3628800 11 39916800 12 479001600 13 1932053504 14 1278945280 15 2004310016 16 2004189184 17 -288522240 18 -898433024 19 109641728 20 -2102132736 21 -1195114496 22 -522715136 23 862453760 24 -775946240 25 2076180480 26 -1853882368 27 1484783616 28 -1375731712 29 -1241513984 30 1409286144 31 738197504 32 -2147483648 33 -2147483648 34 0 35 0 36 0 36の階乗以降0です。 計算結果が正となるが、結果が違うモノ(例えば、13!や31!)は単精度で約10桁程度しか有効数字が得られないためであると思われるのですが、負になったり、0になる理由が分かりません。

  • C言語のプログラムで質問です。

    C言語のプログラムで質問です。 ヤコビ法で固有値・固有ベクトル絵を求めたいのですが、固有値は上手く出るのですが、 固有ベクトルがめちゃくちゃな値が出ます。何が間違っているのでしょうか教えてください。下のは一応自分で作ってみたプログラムです。 #include <stdio.h> #include <math.h> #define N 4 #define PI 3.14159 void jacobi(double a[N][N], double λ[N], double v[N][N]); int main(void) { int i, j; double a[N][N], λ[N], v[N][N], x; for(i=0;i<N;i++){ printf("\n a[%d][0] a[%d][1] a[%d][2] a[%d][3]=",i,i,i,i); scanf("%lf %lf %lf %lf",&a[i][0],&a[i][1],&a[i][2],&a[i][3]); } jacobi(a, λ, v); for(j=0; j<N; j++){ printf("\n固有値λ[%d]=%lf", j, λ[j]); printf("\n固有ベクトル\n"); for(i=0; i<N; i++){ printf("%lf\n", v[i][j]); } } return 0; } /* ヤコビ法による固有値計算 */ void jacobi(double a[N][N], double λ[N], double v[N][N]) { int i, j, kmax=100, repeat, p, q; double eps, c, s,theta, gmax; double apq, app, aqq, apqmax, apj, aqj, vip, viq; gmax=0.0; for(i=0; i<N; i++){ s=0.0; for(j=i+1; j<N; j++){ s += fabs(a[i][j]); } if(s>gmax) gmax=s; } eps=0.000001*gmax; for(i=0; i<N; i++){ for(j=0; j<N; j++){ v[i][j]=0.0; } v[i][i]=1.0; } for(repeat=1; repeat<kmax; repeat++){ /* 収束判定 */ apqmax = 0.0; for(p=0; p<N; p++){ for(q=0; q<N; q++){ if(p!=q){ apq=fabs(a[p][q]); if(apq>apqmax) apqmax=apq; } } } if(apqmax<eps) break; for(p=0; p<N-1; p++){ for(q=p+1; q<N; q++){ apq=a[p][q]; app=a[p][p]; aqq=a[q][q]; if(fabs(apqmax)<eps) break; /*回転角計算*/ if(fabs(app-aqq)>=1.0e-15){ theta= 0.5*atan(2.0*apq/(app-aqq)); }else{ theta= PI/4.0; } c = cos(theta); s = sin(theta); a[p][p] = app*c*c + 2.0*apq*c*s + aqq*s*s; a[q][q] = app*s*s - 2.0*apq*c*s + aqq*c*c; a[p][q] = 0.0; a[q][p] = 0.0; for(j=0; j<N; j++){ if(j!=p && j!=q){ apj = a[p][j]; aqj = a[q][j]; a[p][j] = apj*c + aqj*s; a[q][j] = -apj*s + aqj*c; a[j][p] = a[p][j]; a[j][q] = a[q][j]; } } /*固有ベクトル*/ for(i=0; i<N; i++){ v[i][p] = v[i][p]*c+v[i][q]*s; v[i][q] = -v[i][p]*s+v[i][q]*c; } } } eps=eps*1.05; } for(i=0; i<N; i++) λ[i] = a[i][i]; }

  • Rubyのプログラムについて

    Rubyのプログラムについて、宜しければ教えてください。 def fct(n, f=1) if n<=1 then f else fct(n-1, n*f) end end def factorial(n) (1..n).inject{|x,y| x*y} end def factorial(n) eval( [*(1..n)].join("*") ) end このプログラムが、階乗を計算するメソッドになっているみたいなのですが、なぜコレだけで階乗が計算できるのでしょうか? 宜しければ教えてください><

    • ベストアンサー
    • Ruby