• ベストアンサー

γ関数のプログラム(初心者です)

以下のようにγ関数のプログラムを組みました。 とりあえず整数値を入力すれば、正しい値は返しているということが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); }

質問者が選んだベストアンサー

  • ベストアンサー
  • nakashi
  • ベストアンサー率51% (21/41)
回答No.2

>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だよ

acac
質問者

お礼

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

その他の回答 (3)

  • a-kuma
  • ベストアンサー率50% (1122/2211)
回答No.4

質問で提示されたソースがアルゴリズムとしてはほぼあっている、という前提で 元のソースを見直してみました。 # というのも、手持ちのΓ関数算出のプログラムと結果が違うんで :-) 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; }

acac
質問者

お礼

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

  • GINO
  • ベストアンサー率36% (18/50)
回答No.3

関数の中では printf("4 %lf\n",y); %lfとしていて、 メイン関数では print("%f\n",y); とかにしていませんか? 出力の型が違うのではないかと…。現在のソースを見ていないのでなんとも言えませんが…。

acac
質問者

お礼

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

  • ranx
  • ベストアンサー率24% (357/1463)
回答No.1

4で値を確認できた後のセグメンテーションフォールトといったら ここしかないのでは。 printf("%f\n",y);   ↓ printf("%lf\n",y);

acac
質問者

お礼

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

関連するQ&A