n!の値を普通に求めて、それをスターリングの公式で求めたn!と比較するプログラミングを作る宿題がでたのですが、
n^n√2πn/e^n(1+1/12n+1/288n^2)
の公式を与えられました。
n^nやe^nをそのまま使うと数が大きくなりすぎるので、より正確な数字を求めるためにいったん自然対数におきかえるように指示されています。数学がまったくできないので、ある人に自然対数を使って書き換えるてもらったら、
logΓ(x)=(x-1/2)logx-x+(1/2)log2π+Σ[n=1,∞](-1)^nB_2n/2n(2n-1)x^(2n-1)
という式をもらったのですが、Σや∞の使い方もわからないし、Bっていうのがなになのかすらわかりません。
C++も初心者なうえ数学もまったくだめでとてもこまっています。
いったんlogに置き換えるというのはこういう意味ではないのでしょうか、
n^n√2πn/e^n(1+1/12n+1/288n^2) を途中でわけてそれをlogにおきかえ
(n^n√2πn/e^nのlogと1+1/12n+1/288n^2)のlogを別々に求め*というふうに)
最終的にまた戻すというふうに理解した方がいいのでしょうか。
それと
n^n√2πn/e^n(1+1/12n+1/288n^2)
=pow(n,n)*sqrt(2*PI*n))/exp(n)*(1+1/12*n+1/288*n*n)
この書き方であってますか。
わかりにくい点があれば補足しますので、お願いします。

このQ&Aに関連する最新のQ&A

A 回答 (1件)

厳しいことを言いますが、まず、式の書き方からしてなっていないですね。


>n^n√2πn/e^n(1+1/12n+1/288n^2)
これではどんな式なのかわかりませんよ。ルートはどこまでかかっているのですか?
e^の次はどこまでがeの肩にのっているのですか?
プログラムではきちんとそこをふまえて式を書かないといけないはずですよね。
スターリングの公式は近似の公式なので、どこまで近似の項を使うかによって出てくる誤差も変わってきます。
そこて、先生はこの式を使いなさいと示したわけです。多分先生の出した式は、

n! = (n)^(n)×sqrt(2πn)/[e^{n×(1+n/12+(n)^(2)/288)}]

ですね?
友人が答えてくれた式は、大本の式なので上記の自然対数をとった式ではありません。なので、その式を使うと誤差の値は課題の求める答えと異なります。
また、式は始めに自然対数をとってから計算しないとnが大きいときにはうまく行きません。
つまり、
ln(n!) = ~
の形になおします。普通はこの公式はこちらの表記が一般的です。(特にnが大きいときにこの公式を使うことが多いため)
ln(A) は e を底辺とする log を特別に log ではなくて ln と表記します。
変換にするのは難しい作業ではありません。
1) ln(A^B) = B×ln(A)
2) ln(A×B) = ln(A) + ln(B)
3) ln(A/B) = ln(A) - ln(B)
4) ln(e^A) = A×ln(e) = A
使う変換式は上の4つです。

まず式全体をln{ }の中にいれてから、2), 3), 4) でかけ算、わり算を全部足し算、引き算に展開します。
あとは1を使ってべき乗(x^yの形)をかけ算にします。ルートは x^(1/2) になります。

宿題というのは勉強してもらうために先生が出すモノですから、あえて答えは書きません。
自分の頭で考えて、計算して初めに身に付きます。
勉強するために宿題をもらっているのですから、あとはがんばって下さい。
    • good
    • 0
この回答へのお礼

わかりやすい説明ありがとうございます。
とても参考になりました。
しっかりと理解するには時間がかかりそうですが、
後は自分でできそうです。
がんばります!!

お礼日時:2001/10/25 17:36

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QC言語についてです 整数nを入力すると、1+2+3...+nの 合計値を出力するプログラムを作りたい

C言語についてです
整数nを入力すると、1+2+3...+nの
合計値を出力するプログラムを作りたいの
ですが
これではなぜできないのでしょうか?

Aベストアンサー

初心者がよくやる間違いです。
気をつけましょう。


教科書等には
 for(〜) { 処理 }  で「処理」を繰り返す
等と書いてありますが、処理が1命令だけの場合
 for(〜) 命令 ;
と書くこともできます。この場合、forの条件に従って「命令」を繰り返すことになります。
この命令には「何もしない」命令、つまり、「空白」も該当します。
つまり
 for(〜);
で、「何もしない」を繰り返すfor文となります。

また、 {} は、 forとか if とかの後でなくても利用できます。
そのときには{文1;文2;...} といいた複数の文を、一つの文として扱う、という意味になります。
これは、 { } をはずしたのと同等です。 (forとかifとかの後等の特定の条件でなければ)

つまり
for(〜) { 処理 }
のつもりで
for(〜) ; { 処理 }
と書いてしまうと

for(〜) ; で「何もしない命令」を繰り返し実行
↓その後
{処理}を (1回だけ)実行

となります。



※ なお、上記は理解しやすいように、ちょっと不正確な部分があります。

初心者がよくやる間違いです。
気をつけましょう。


教科書等には
 for(〜) { 処理 }  で「処理」を繰り返す
等と書いてありますが、処理が1命令だけの場合
 for(〜) 命令 ;
と書くこともできます。この場合、forの条件に従って「命令」を繰り返すことになります。
この命令には「何もしない」命令、つまり、「空白」も該当します。
つまり
 for(〜);
で、「何もしない」を繰り返すfor文となります。

また、 {} は、 forとか if とかの後でなくても利用できます。
そのときには{文1;文2;...} といいた複数...続きを読む

QC言語についてです 整数 nを入力すると、1+2+3...+n という計算式を出力するには どうすれ

C言語についてです
整数 nを入力すると、1+2+3...+n
という計算式を出力するには
どうすればよいでしょうか?

Aベストアンサー

#include <stdio.h>

int main(void) {
 int n, i = 1;
 scanf("%d", &n);
 while(i <= n) {
  if (i == n)
   printf("%d\n", i);
  else
   printf("%d+", i);
  i++;
  }
 return 0;
}

QC言語です 整数nを入力すると1+2+....+nという計算式と 合計値を出力するプログラムを作りた

C言語です
整数nを入力すると1+2+....+nという計算式と
合計値を出力するプログラムを作りたいの
ですが
このようになってしまいます
なぜでしょうか?

Aベストアンサー

printf("+%d=",i); → printf("+%d",i);
printf("%d",sum); → printf("=%d",sum);

でそ?

Qint select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)について

見当違いな質問かもしれませんがお願いします。

複数のソケットを監視する際にselectを使う場合のことですが、
selectの動作と戻り値について疑問があります。

http://www.linux.or.jp/JM/html/LDP_man-pages/man2/select.2.html
ここを参照すると、selectの戻り値は
「更新された 3 つのディスクリプタ集合に含まれているディスクリプタの数 (つまり、 readfds, writefds, exceptfds 中の 1 になっているビットの総数) を返す。」
とあります。
私の中でselectは登録してあるFDのうち、一つでも動きがあれば即座にselectを抜けるもの、という認識です。
この認識だとreadfds,writefdsが引数として与えられているとしても、
どちらかのfd_setのうち、一つでも動きがあればselect文は
抜けてしまうことになります。とすると、戻り値として
「readfds, writefds, exceptfds 中の 1 になっているビットの総数」
は常に1ということになってしまいます。しかし、総数というからには
複数同時に1になることもあるはずです。

私の認識が間違っているとは思うのですが、どう間違っているのかわかりません。
select文の動きについて詳しく教えていただけないでしょうか。
または良いページがあれば教えてください。

見当違いな質問かもしれませんがお願いします。

複数のソケットを監視する際にselectを使う場合のことですが、
selectの動作と戻り値について疑問があります。

http://www.linux.or.jp/JM/html/LDP_man-pages/man2/select.2.html
ここを参照すると、selectの戻り値は
「更新された 3 つのディスクリプタ集合に含まれているディスクリプタの数 (つまり、 readfds, writefds, exceptfds 中の 1 になっているビットの総数) を返す。」
とあります。
私の中でselectは登録してあるFDのうち、一つでも動きが...続きを読む

Aベストアンサー

>私の中でselectは登録してあるFDのうち、一つでも動きがあれば即座にselectを抜けるもの、という認識です。
この認識はあっています。
しかし、selectを呼び出す以前にOKになっているFDがあれば、それらは全てビットがONになります。

話しを簡単にする為に、受信のみのソケットを3つ作成したとします。
これらの3つのソケットに向けて相手が電文を送ったとします。
その状態でまだ、こちらはselectを呼び出さずにいます。しばらくしてから、selectを呼び出すと、selectは即座にリターンし、3つのビットが一度にONになっているはずです。
一方、相手が、一切電文を送ってない状態で、selectを呼び出した場合は、何れかのビットがONになればリターンするので、そのときは、貴方が想像しているように
ビットの総数は1になる可能性が高いです。
従って、相手が電文を送る前にselectを呼び出すか、送った後にselectを呼び出すかは、その時のタイミングにより異なります。従って、ビット数の総和が常に1であるとは、考えない方が無難です。(1つのソケットしか使用しない場合は別ですが・・・)

>私の中でselectは登録してあるFDのうち、一つでも動きがあれば即座にselectを抜けるもの、という認識です。
この認識はあっています。
しかし、selectを呼び出す以前にOKになっているFDがあれば、それらは全てビットがONになります。

話しを簡単にする為に、受信のみのソケットを3つ作成したとします。
これらの3つのソケットに向けて相手が電文を送ったとします。
その状態でまだ、こちらはselectを呼び出さずにいます。しばらくしてから、selectを呼び出すと、selectは即座にリターンし、3つのビ...続きを読む

Qx^2+2x+1=0

x^2+2x+1=0をとく関数プログラムです。
うまくできません。どこが間違っているのでしょうか。
教えて下さい。

#include<stdio.h>
#include<math.h>

void input_keisuu(double a,double b,double c);
void solve(double a,double b,double c);


int main(void)
{
double a,b,c;

input_keisuu(a,b,c);
solve(a,b,c);
return 0;
}

void input_keisuu(double a,double b,double c)
{
puts("二次関数a*x^2+b*x+c=0を解きます。");

a=1;
b=2;
c=1;

puts("a=1");
puts("b=2");
puts("c=1");


}

void solve(double a,double b,double c)
{
double d;
double x;

d=b*b-4*a*c;

printf("判別式d= %f\n",d);

x=(-b+ sqrt(d))/(2*a);

printf("二つの解のうち大きい方はx=%f\n",x);

}

x^2+2x+1=0をとく関数プログラムです。
うまくできません。どこが間違っているのでしょうか。
教えて下さい。

#include<stdio.h>
#include<math.h>

void input_keisuu(double a,double b,double c);
void solve(double a,double b,double c);


int main(void)
{
double a,b,c;

input_keisuu(a,b,c);
solve(a,b,c);
return 0;
}

void input_keisuu(double a,double b,double c)
{
puts("二次関数a*x^2+b*x+c=0を解きます。");

a=1;
b=2;
c=1;

puts("a=1");
puts("b=2...続きを読む

Aベストアンサー

input_keisuu関数でセットした係数が、
solve関数に渡っていません。
input_keisuu関数の引数は、各係数のアドレスにしてください。


このカテゴリの人気Q&Aランキング

おすすめ情報