以下のようにγ関数のプログラムを組みました。
とりあえず整数値を入力すれば、正しい値は返しているということがprintfの4で確認できました。
もとはfortranで組んだプログラムをCに置き換えました。
ですが、実際走らせてみると、4で値は確認できますがsegmentation faultが出てしまいます。
ですからサブルーチンファイル(ユーザー関数?)として利用できません。
何がいけないのでしょうか?
正しくyが帰ってくるようにどうなおしたらよいのか教えてください。








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

double gamma(double x)
{
double c[8],y,a,r,b,s;
int i;
a=1.;
r=1.;

c[1]=5.771916e-01;
c[2]=9.882058e-01;
c[3]=8.970569e-01;
c[4]=9.182068e-01;
c[5]=7.567040e-01;
c[6]=4.821993e-01;
c[7]=1.935278e-01;
c[8]=3.586834e-02;


printf("0 %f\n",x);

while(1){
if(x>2.){
x=x-1.;
a=a*x;
printf("1 %f %f\n",x,a);
}
else if(x<1.){
a=a/x;
x=x+1.;
printf("2 %f %f\n",x,a);
}
else{
break;
}
}
x=x-1.;
for(i=1;i<8;i++){
b=(double)(i);
s=(c[i]*((double)(pow(-1,b))) *((double)(pow(x,b))));
printf("3 %d %f\n",i,c[i]);
r=r+s;
}
y=a*(r+(0.03586834*((double)(pow(-1,8)))*((double)(pow(x,8)))));
printf("4 %f\n",y);
return y;
}

main()
{
double x,y;
printf("数字を入力してください。");
scanf("%lf",&x);
printf("メインプログラム %lf\n",x);
y=gamma(x);
printf("%f\n",y);
}

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

A 回答 (4件)

>double c[8],y,a,r,b,s;



double c[9],y,a,r,b,s;
にするか
>c[1]=5.771916e-01;
>c[2]=9.882058e-01;
>c[3]=8.970569e-01;
>c[4]=9.182068e-01;
>c[5]=7.567040e-01;
>c[6]=4.821993e-01;
>c[7]=1.935278e-01;
>c[8]=3.586834e-02;
c[0]=5.771916e-01;
c[1]=9.882058e-01;
c[2]=8.970569e-01;
c[3]=9.182068e-01;
c[4]=7.567040e-01;
c[5]=4.821993e-01;
c[6]=1.935278e-01;
c[7]=3.586834e-02;
にしてみれば

c[8]のとき添え字は0-7だよ
    • good
    • 0
この回答へのお礼

おっしゃった通りなおしてみたら、Segmentation Faultは解消しました。
…ですが、4で確認できる値と(これは正しい値)メイン文で出力される値(変な値)が異なってしましました。
関数側の値がちゃんと出力されるためにはどうしたらいいんですか??
もし、よかったらお願いします。

お礼日時:2002/03/28 20:19

質問で提示されたソースがアルゴリズムとしてはほぼあっている、という前提で


元のソースを見直してみました。

# というのも、手持ちのΓ関数算出のプログラムと結果が違うんで :-)


Segmentation Fault の原因は nakashi さんが書かれている通り、C 言語の配列は
添え字が0から始まる、ということです。

それを直すには、nakashi さんが書かれているだけでは、ちょっと足りません。
以下に見直してみたソースを載せておきます。

コメントで /* ※ */ が入っているところが変更点です。一ヶ所を除いて、添え字の
見直しをしただけです。


double gamma(double x)
{
double c[8],y,a,r,b,s;
int i;
a=1.;
r=1.;

c[0]=5.771916e-01; /* ※ */
c[1]=9.882058e-01; /* ※ */
c[2]=8.970569e-01; /* ※ */
c[3]=9.182068e-01; /* ※ */
c[4]=7.567040e-01; /* ※ */
c[5]=4.821993e-01; /* ※ */
c[6]=1.935278e-01; /* ※ */
c[7]=3.586834e-02; /* ※ */


printf("0 %f\n",x);

while(1){
if(x>2.){
x=x-1.;
a=a*x;
printf("1 %f %f\n",x,a);
}
else if(x<1.){
a=a/x;
x=x+1.;
printf("2 %f %f\n",x,a);
}
else{
break;
}
}
x=x-1.;
for(i=0;i<8;i++){ /* ※ 8回のループで良いですよね? */
b=(double)(i+1); /* ※ */
s=(c[i]*((double)(pow(-1,b))) *((double)(pow(x,b))));
printf("3 %d %f\n",i+1,c[i]); /* ※ */
r=r+s;
}
y=a*(r+(0.03586834*((double)(pow(-1,8)))*((double)(pow(x,8)))));
printf("4 %f\n",y);
return y;
}
    • good
    • 0
この回答へのお礼

アドバイスありがとうございます。
配列にかんしては、問題解消しました。
Segmentation faultも出ません。
ですが、正しい値がメインの出力にかえってきません。
関数の中では4で正しい値が確認できるのに、メイン文の出力では全然関係ない数字がでてしまいます。
これは、どうやったら治るのか良かったらまたアドバイスください。

お礼日時:2002/03/29 17:46

関数の中では



printf("4 %lf\n",y);

%lfとしていて、

メイン関数では

print("%f\n",y);

とかにしていませんか?
出力の型が違うのではないかと…。現在のソースを見ていないのでなんとも言えませんが…。
    • good
    • 0
この回答へのお礼

確かめてみましたが、大丈夫でした。
現在のソースファイルは、先ほどの方がおっしゃってくださったアドバイスどおり配列の数を直しただけです。
良かったら、またアドバイスください。
ありがとうございます。

お礼日時:2002/03/28 22:42

4で値を確認できた後のセグメンテーションフォールトといったら


ここしかないのでは。
printf("%f\n",y);
  ↓
printf("%lf\n",y);
    • good
    • 0
この回答へのお礼

どうもこれではなおらないようでした。
アドバイスありがとうございました。

お礼日時:2002/03/28 22:43

このQ&Aに関連する人気のQ&A

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

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

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

Qガンマ関数について

ガンマ関数の漸近展開のやりかたがわかりません。よろしくお願いします。

Aベストアンサー

以下のURLに導出方法が紹介されているようである。

---------------------------------------
http://wapedia.mobi/ja/%E3%82%B9%E3%82%BF%E3%83%BC%E3%83%AA%E3%83%B3%E3%82%B0%E3%81%AE%E5%85%AC%E5%BC%8F
---------------------------------------

Q{x = x>y ? x:y; return x;}

#include <iostream>
using namespace std;

inline int max(int x, int y){x = x>y ? x:y; return x;}

int main()
{
int num1, num2, ans;

cout << "2つの整数を入力して。\n";
cin >> num1 >> num2;

ans = max(num1, num2);

cout << "最大値は" << ans << "です。\n";

return 0;
}
の{x = x>y ? x:y; return x;}の部分の意味が解りません。

Aベストアンサー

inline int max(int x, int y){x = x>y ? x:y; return x;}
これを普通に関数で書くと

int max(int x, int y)
{
x = x>y ? x:y;
return x;
}

です。

x = 部分は右辺の結果が代入されます。これはわかりますよね。
x>y?x:y;
と書くと?より左にある条件式を判定し、その結果が真である場合は:で区切られた左側の値を、偽である場合は右の値を帰します。
x>yが真であればxを、偽であればyを返します。
それが、左辺値xに代入され、関数の戻り値として帰ります。

従って、2つの値をこの関数に入れると、大きいほうの値が帰ることになります。

Q漸近線を求めるときの場合分け

タイトルの通りなのですが、漸近線の求め方について質問です。よろしくお願いします。
漸近線の基本的な求め方は、1、y軸に平衡な漸近線、2、y軸に平衡でない漸近線、とあります。

これを使って
問題1、y=(x^2-x+1)/(x-1)の漸近線を求めよ。
問題2、y=2x+(x^2-1)^(1/2)の漸近線を求めよ。
です。

解答は、問題1では式を変形して、漸近線を予想して、解いています。問題2では、明らかに、y軸に平行な漸近線はない、として、y軸に平行でない漸近線を求めています。

ですが、ここで質問です。問題1では、予想して求めていますが、これは入試の解答方法としていいのでしょうか。また、問題
で、明らかにy軸に平行な漸近線はない、としていますが、グラフもかけないで、どうしてそのようにいいきれるのでしょうか。ただ、これには、注として、グラフの概形は、y=2xとy=(x^2-1)^(1/2)の和曲線を考えるとありました。が、これの意味もよくわからないのです。

勉強不足ですが、どなたか存知の方、アドバイスをいただけませんか。よろしくお願いします。

タイトルの通りなのですが、漸近線の求め方について質問です。よろしくお願いします。
漸近線の基本的な求め方は、1、y軸に平衡な漸近線、2、y軸に平衡でない漸近線、とあります。

これを使って
問題1、y=(x^2-x+1)/(x-1)の漸近線を求めよ。
問題2、y=2x+(x^2-1)^(1/2)の漸近線を求めよ。
です。

解答は、問題1では式を変形して、漸近線を予想して、解いています。問題2では、明らかに、y軸に平行な漸近線はない、として、y軸に平行でない漸近線を求めています。

ですが、ここで質問で...続きを読む

Aベストアンサー

y=ax+bがy=f(x)の漸近線であれば、必ず

f(x)-(ax+b)→0 (x→∞) ・・・★
(当然、x→-∞の漸近線を考えるのであれば、x→-∞です。以下同様)

が成り立ちます。逆に、これが成り立てば、ほぼy=ax+bは漸近線であると考えて差し支えありません。(ほぼと書いたのはy=f(x)とy=ax+bが交わる可能性があるから)

したがって、このようなa,bが(何らかの予想をたてて)見つかったのであれば、y=ax+bが漸近線として大きな問題は起こりません。
>問題1では、予想して求めていますが、これは入試の解答方法としていいのでしょうか。
具体的にどのような解答なのか分かりませんが、多分、問題ありません。

ちなみに、実際に、このようなa,bを計算で求めるとしたら、
a=lim[x→∞]f(x)/x (★をxで割ってx→∞としたもの)
としてaを求めます。このaを元に
b=lim[x→∞](f(x)-ax)
としてbを求めます。(もちろん、これらが収束する保証はありませんが、収束しないのなら、漸近線を持たないという事です)


>また、問題
>で、明らかにy軸に平行な漸近線はない、としていますが、グラフもかけないで、どうしてそのようにいいきれるのでしょうか。
y軸に平行な漸近線というのは、y=1/xにおけるy軸とか、y=tanxにおける、直線x=π/2のような奴です。
要するにf(x)がx→α(有限の値)で発散するような奴です。ほぼ100%、分母が0になるような奴です。
>y=2x+(x^2-1)^(1/2)
は、途中で発散することがないので(いたるところで連続ですから)、y軸に平行な漸近線を持ちません


>ただ、これには、注として、グラフの概形は、y=2xとy=(x^2-1)^(1/2)の和曲線を考えるとありました。

「南京玉すだれ」って分かりますか?
http://www.eonet.ne.jp/~tosimaru/
↑こんなのです。これの竹串(?)って、何か竹串に平行な方向にずれますよね。
※各竹串は、普通全部同じ長さですが、それぞれ長さが違うとしましょう(y=f(x)の形)

この竹串が垂直になるように、水平な面に置くと、すだれの上端はy=f(x)という形状になっているはずです。

でも、坂道に置くと(各竹串の下端を地面につける)、すだれの上端はy=f(x)という形にはなってませんよね。
坂道の高さ(?)+すだれの高さ(=f(x))
っていう感じの形になっているのがイメージできませんかね?

これと同じように、
y=2xという「坂道」の上に、√(x^2-1)という形の「すだれ」を置いている、というイメージで
y=2x+√(x^2-1)というグラフの形状をイメージしてみよう、
という感じの意味ですね。
(・・・って、上手く説明できません。。。図は書けないし、日本語は下手なので、分からなかったら、やんわりとスルーしてあげてくださいw)

y=ax+bがy=f(x)の漸近線であれば、必ず

f(x)-(ax+b)→0 (x→∞) ・・・★
(当然、x→-∞の漸近線を考えるのであれば、x→-∞です。以下同様)

が成り立ちます。逆に、これが成り立てば、ほぼy=ax+bは漸近線であると考えて差し支えありません。(ほぼと書いたのはy=f(x)とy=ax+bが交わる可能性があるから)

したがって、このようなa,bが(何らかの予想をたてて)見つかったのであれば、y=ax+bが漸近線として大きな問題は起こりません。
>問題1では、予想して求めていますが、これは入試の解答方法としていいのでし...続きを読む

Qint i,j; \n i=0,j=5;

int i,j;
i=0;
j=5:
と書いてあるソースは普通ですが、
int i,j;
i=0,j=5:
と書いてあるソースもあります。
後者はC++の正しい書式ですか?

カンマ演算子というのは後者のカンマのことですか?

Aベストアンサー

 正しい書式です。

i=0,j=5;
 における、「,」をカンマ演算子といいます。2項の演算子です。カンマで区切られた演算を「左から順番に」実行し、最後の演算を結果として返します。
 したがって、例の文であれば、i=0を実行し、次にj=5を実行。そして、j=5の結果の5を結果として返します。
 ・・・
 が、本来的には、あまり、例のような使い方はしませんね。よく見られるのは、次のような場合です。

 for (i=0,j=0 ; i < 50 ; ++i,++j) {

 のような形でよく見られます。for文の各式は、一つの式でなければならないので、こんな書き方をするわけです。初期化と更新部が一つにまとまり、ループが読みやすくなるのが利点かな。

Qガンマ関数とベータ関数

積分計算でガンマ関数とベータ関数が使えそうだと判断する基準を教えてください。

Aベストアンサー

 ガンマ関数やベータ関数と言わず、特殊関数と言われるものは皆、ある特定の数学的状況を処理するために生まれた、というのが最初の動機付けです。

 ガンマ関数は最も初等的には、整数で定義されていた階乗を、ある理由のもとに(ある特定の数学的状況を処理するために)、実数まで拡張したものです。最終的には複素数にまで拡張されますが、関連するガンマ関数の公式群、ワイヤシュトラウスやハンケルの積分表示,スターリングの近似式などはどれも、特定の数学的状況に動機があります。

 ところがそういう風に色々な特殊関数を詳細に調べて行くと、例えばベータ関数とガンマ関数の関連がわかり、色々な特殊関数を、ある程度統一的に理解できないか?という話になって行きます。そこから特殊関数論が始まって、#2さんの仰るような方向にも話は発展するのだと思います。

 ただ実用的には、「ガンマ関数とベータ関数が使えそうだと判断する基準」は何か?と問われれば、ガンマ関数やベータ関数の動機付けとなった数学的状況と、与えられた数学的状況が似ているかどうかを、見抜ける目を持っているか、持っていなくても状況を調査(分析)した結果そうだったと言えるかどうかだと、言わざる得ません。この態度を、言葉を切り詰めて短く言うと、#1さんの、

>使ってみて使えたら、使える。
>それ以上でも以下でもない。

になると思えます。

 ガンマ関数やベータ関数と言わず、特殊関数と言われるものは皆、ある特定の数学的状況を処理するために生まれた、というのが最初の動機付けです。

 ガンマ関数は最も初等的には、整数で定義されていた階乗を、ある理由のもとに(ある特定の数学的状況を処理するために)、実数まで拡張したものです。最終的には複素数にまで拡張されますが、関連するガンマ関数の公式群、ワイヤシュトラウスやハンケルの積分表示,スターリングの近似式などはどれも、特定の数学的状況に動機があります。

 ところがそういう...続きを読む

Qprintf( "%d", i % 10 );で?

int count;
int i;
scanf( "%d", &count );
for( i = 0 ; i < count ; i++ )
printf( "%d", i % 10 );「iを10で割った余り」だそうです。
i%5とした場合、 
 仮に5と入力すれば、01234と表示すると思いますが、
何でiを5で割れば5進数みたいにコンピュータが認識するのですか?
理論だけ勉強中で、実際試したことがありません? 
よろしくお願いします。

Aベストアンサー

例えば、246を例に考えてみます。

246を5で割ると49で余りが1

これは書き換えると
246 = 49x5 + 1 という事ですね。

次に49について同様に行なうと
49を5で割ると9で余りが4

これは書き換えると
49 = 9x5 + 4という事ですね。

最初の結果とあわせると、
246 = 9(x5x5) + 4(x5) + 1
という事ですね。

同様に9についても計算すると

246 = 1(x5x5x5) + 4(x5x5) + 4(x5) + 1

となります。


5で割った答えと5で割った余りは、5進数で一つ上の桁へ移せる部分とその桁に残る部分を分けている事になります。
10進数でも32を考えた時、30の部分は上の桁に移せる部分で(10で割った答え部分)2はその桁に残る部分(2 = 32 % 10)ですよね。

Q漸近線の求めかた??

y=x+1+1/(x-1)のグラフを描く問題なんですが、増減表(添付図)を書いた後教科書では次のように漸近線を求めています。

lim[x]→1+0]y=∞, lim[x→1-0]y= ー∞であるからx=1はこの曲線の漸近線である。
さらに
lim[x→∞]{y-(x+1)}=0
lim[x→-∞]{y-(x+1)}=0
だからy=x+1もこの曲線の漸近線である。

[質問1] どういうわけで増減表を書いた後漸近線を求めたいと考えたのでしょうか?双曲線であると分かった上での判断ですか?
 
[質問2] 漸近線を求めるとき、なぜ、まるでy=x+1が漸近線であるとあらかじめしっているかのように
リミットの中の式をlim[x→∞]{y-(x+1)}=0 という形にしているのでしょうか?
(これで確かにy=x+1は漸近線ということがわかりますけど・・)

漸近線を求める上での考え方がよくわかりません。意味不明な箇所があるかもしれませんが、教えてください。

Aベストアンサー

> [質問1] どういうわけで増減表を書いた後漸近線を求めたいと考えたのでしょうか?双曲線であると分かった上での判断ですか?

増減表を描いた後に漸近線がある事に気付いたわけではなく、
y = x + 1 + 1/(x-1)という式を見た瞬間に気付くんです。

> [質問2] 漸近線を求めるとき、なぜ、まるでy=x+1が漸近線であるとあらかじめしっているかのように

ちょっと大雑把な考え方かもしれませんが、
y = x + 1 + 1/(x-1)がx → ∞の時(また、x → -∞の時)に
どうなるのかを想像してみるとよいです。
特に、右辺のそれぞれの項がどうなるかを考えると良いです。

x がどんどん大きくなると、x + 1 + 1/(x-1)の中の3つの項のうち、
1/(x - 1)だけは0に収束して消えていってしまいませんか?
そうなると残るのはxと+1の項だけになります。
なのでy = x + 1 + 1/(x-1)は、xがどんどん大きくなると
y = x + 1に近づくと考える事ができます。

y = (2x^2 + 5) / (x + 2)のような形の関数だと、
そのままではこのような考え方ができません。
この場合は割り算をして
y = 2x - 4 + (13/(x + 2))と変形してやると、
同じように考える事ができます。

他にも例えば、y = 2x + 3 + 2^xはx → -∞の時、
y = 2x + 3に漸近します(x → +∞では漸近しません)。
後は「漸近放物線」みたいのも考えられます。
例えばy = x^2 + 2x + (1/x)は、x → +∞とx → -∞の時、
放物線y = x^2 + 2xに漸近します。

> [質問1] どういうわけで増減表を書いた後漸近線を求めたいと考えたのでしょうか?双曲線であると分かった上での判断ですか?

増減表を描いた後に漸近線がある事に気付いたわけではなく、
y = x + 1 + 1/(x-1)という式を見た瞬間に気付くんです。

> [質問2] 漸近線を求めるとき、なぜ、まるでy=x+1が漸近線であるとあらかじめしっているかのように

ちょっと大雑把な考え方かもしれませんが、
y = x + 1 + 1/(x-1)がx → ∞の時(また、x → -∞の時)に
どうなるのかを想像してみるとよいです。
特...続きを読む

Qtry{}catch(){}とデストラクタの関係を教えてください。

try-catchでメモリ確保を含むクラスをスローした場合、デストラクタはどの時点で働くのか、教えてください。たとえば、↓の使いかたは大丈夫でしょうか?

【1】
try{
 throw(CError(100, "エラー情報"));
}catch(CError& err){
 //ここでerrを参照しても問題ないのでしょうか?
}

【2】
try{
 CError err(100, "エラー情報");
 throw(err); // (1)
}catch(CError& err){
 //ここでerrを参照しても問題ないのでしょうか?
 //まだデストラクタはちゃんと動作するのでしょうか?
 //catchが呼び出し元のメンバであったりしても大丈夫なのでしょうか?
}

宜しくお願いします。

Aベストアンサー

【1】【2】どちらの場合も問題がありません。
コンパイラが必要に応じてerrオブジェクトのコピーを作成します。
デストラクタが呼び出されるタイミングはコンパイラに依存するところもあると思いますが、
例えばVC7.1では【2】は以下のように動作します。
(1) errオブジェクトのコンストラクタが呼び出される
(2) CErrorクラスのテンポラリオブジェクト(以下a)のコピーコンストラクタが呼び出される。
(3) errオブジェクトのデストラクタが呼び出される
(4) catch文まで到達
(5) aオブジェクトのデストラクタが呼び出される。

VC7.1では、【1】は以下のように動作します。
(1) errオブジェクトのコンストラクタが呼び出される
(2) catch文まで到達
(3) errオブジェクトのデストラクタが呼び出される。

コンパイラがオブジェクトのコピーを省略しているようです。

Q数IIIグラフ・漸近線に関する質問です。

いつもお世話になり、ありがとうございます。今回も宜しくお願い致します。

今回は問題ではなく、私自身の疑問についてなのですが、数IIIのグラフを描く際に求める漸近線についてです。

例えば、f(x)=(x^2+x-5)/(x-2)のグラフの漸近線を求める場合、
f(x)=(x+3) + {1/(x-2)} という形に変形させて、漸近線はy=x+3とx=2だと求められると思います。

そこで質問なのですが、漸近線の関数は上のように必ず1次関数なのでしょうか。

解いていた問題の中で、

y= x^2 + (1/x^2) のグラフを求める問題があって、この場合、1/x^2という分数関数の前のx^2は漸近線になるのではないかと思いました。
理由は、x→∞のとき、{f(x)-x^2}→0 になるからです。
でも、(確実に私の経験不足ですが)いままでに漸近線は1次関数以外見たことがないため、私が間違っているのか分からず困っています。

数IIIのグラフを描く際の漸近線は必ず1次関数までなのでしょうか。

お手数をおかけしますが、宜しくお願い致します。

Aベストアンサー

漸近線の定義に1次関数に限るとは決して書いていません。いかに高校数学といえどもそんなに理不尽ではありません。教科書をよく見なおしてください。

>y= x^2 + (1/x^2) のグラフを求める問題があって、この場合、1/x^2という分数関数の前のx^2は漸近線になるのではないかと思いました。

その通りです。似たような話がurlに出ています。

参考URL:http://ja.wikipedia.org/wiki/%E6%BC%B8%E8%BF%91%E7%B7%9A

Qprintf("%lf",5/3); は 0.000000 ?

Cを勉強中です。
main(){
printf("%lf",5/3);
}
をBorland C++ 5.5.1コンパイラで
コンパイルして実行すると、
0.000000 と表示されてしまいます
1.666666 と表示するには、何が足りないのでしょうか。

Aベストアンサー

printf("%lf",5/3) の 5/3 は整数の割り算となっています。
5.0のように実数を使ってみてください


人気Q&Aランキング

おすすめ情報