入試の過去問を解いてみたのですが

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
morokosiQ

入試の過去問を解いてみたのですが

#1

投稿記事 by morokosiQ » 4年前

これであってますでしょうか?

http://i.imgur.com/RKxB8fO.png (問題)

コード:

double func( double X0 )
	{
	double X ;
	double ε=0.000001 ; /* 自分で設定した許容誤差です。*/
	X = (-aX0^2+ab^2+c)/2a(b-X0); /*接線のX切片の値*/
	
	while(X0-X=0)
		{
		X = (-aX0^2+ab^2+c)/2a(b-X0); /*接線のX切片の値*/
		if(X0-X<ε)
			{
			return X ;
			}
		X=X0;
		}
	}
		

morokosiQ

Re: 入試の過去問を解いてみたのですが

#2

投稿記事 by morokosiQ » 4年前

code訂正します。

コード:

double func( double X0 )
	{
	double X ;
	double ε=0.000001 ; /* 自分で設定した許容誤差です。*/
	
	while(X0-X=0)
		{
		X = (-aX0^2+ab^2+c)/2a(b-X0); /*接線のX切片の値*/
		if(X0-X<ε)
			{
			return X ;
			}
		X=X0;
		}
	}
		

アバター
みけCAT
記事: 6227
登録日時: 9年前
住所: 千葉県
連絡を取る:

Re: 入試の過去問を解いてみたのですが

#3

投稿記事 by みけCAT » 4年前

morokosiQ さんが書きました:これであってますでしょうか?
問題文中の「Cプログラム」が自分の知っているC言語で書かれたプログラムのことを意味すると仮定すると、大間違いです。
コンパイルすら通らないでしょう。質問する前に自分でテストを行ってください。
手元に開発環境が無い場合、IdeoneWandboxなどが役に立つかもしれません。
  • εは識別子に使えないかもしれません。変数名には英語のアルファベット、アラビア数字、アンダースコア(すべて半角)のみを用いるべきです。
  • aX0、abの定義がありません。掛け算には*演算子を用いるべきです。
  • ^演算子はxorを表し、実数には使えないかもしれません。例えばX0の2乗を計算するには素直にX0*X0と書くべきでしょう。
  • 「2a(b-X0)」は一見関数2aの呼び出しに見えますが、2aのような先頭に数字がある文字列は識別子には使えません。掛け算には*演算子を用いるべきです。
  • =は代入演算子です。等しいかどうかの判定には==演算子を用いるとよいでしょう。また、浮動小数点数の誤差による誤動作を避けるため、「差の絶対値が(適当な小さい数)未満なら等しいとみなす」という実装もいいかもしれません。
  • 最初に「X0-X=0」が成立しなかった場合、もしコンパイルエラーがなかったとしても、Xの値が返りません(返る値が不定または0になります)。
  • もしコンパイルエラーがなかったと仮定すると、最初に不定の値Xを用いた計算がされます。結果が意図しないものになるかもしれません。(わざわざ訂正してさらに劣化させましたか…)
また、(2)の答案が見当たらないですね。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

morokosiQ

Re: 入試の過去問を解いてみたのですが

#4

投稿記事 by morokosiQ » 4年前

コード:

#include <stdio.h>

double func( double X0 )
	{
        int a =3; /*仮定*/
        int b=3;    /*仮定*/
        int c= -3;  /*仮定*/	
	double E=0.000001 ; /* 自分で設定した許容誤差です。*/
	double X = (-a*X0*X0+a*b*b+c)/2*a*(b-X0); /*接線のX切片の値*/
      

	while(X0-X==0)
		{
		X = (-a*X0*X0+a*b*b+c)/2*a*(b-X0); /*接線のX切片の値*/
		if(X0-X<E)
			{
                        printf("%d\n",X);
			return X ;
			}
		X=X0;
		}
	}


int main (void){
       
        func(3);
        printf("%d\n",X);

}

これをcodepad( http://codepad.org/ )で通したのですが、失敗しました。


(2)の解答は
元の関数f(x)のx切片を求める計算をしている。 です。

アバター
Tatu
記事: 445
登録日時: 9年前
住所: 北海道

Re: 入試の過去問を解いてみたのですが

#5

投稿記事 by Tatu » 4年前

x切片の計算は合っているのでしょうか?

g(x)=f'(x0)(x-x0)+f(x0)
でg(x)=0となるxをf(x0),f'(x0)を用いて表現してみてください。

box
記事: 1739
登録日時: 9年前

Re: 入試の過去問を解いてみたのですが

#6

投稿記事 by box » 4年前

morokosiQ さんが書きました:

コード:

	double X = (-a*X0*X0+a*b*b+c)/2*a*(b-X0); /*接線のX切片の値*/
		X = (-a*X0*X0+a*b*b+c)/2*a*(b-X0); /*接線のX切片の値*/
この2つの式で、分母の範囲はどこからどこまでであることを想定されていますか?
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

アバター
みけCAT
記事: 6227
登録日時: 9年前
住所: 千葉県
連絡を取る:

Re: 入試の過去問を解いてみたのですが

#7

投稿記事 by みけCAT » 4年前

  • 5行目に全角スペースがあります。消してください。
  • 「定数a,b,cはこの関数の外側で定義されているとしてよい」という条件なので、
    a,b,cの定義は「double func( double X0 )」の上に書いた方がいいかもしれません。
    (「としてよい」なので間違ってはいないと思いますが、色々な入力に対応できる方がいい気がします)
  • while文の繰り返し条件は妥当ですか?そもそもここで条件判定することは本当に必要ですか?
  • 「X0-X<E」という条件は収束判定として妥当でしょうか?例えばX0=-10000としたらどうなるでしょうか?
  • printfの書式とデータ型が合っていません。double型の値を出力するには%fや%gなどを使用してください。
  • main関数で使用されているXの定義が無いようです。
オフトピック
x0にはb以外の任意の実数が入力されるとする (bは入力されないとは言ってない)
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
Tatu
記事: 445
登録日時: 9年前
住所: 北海道

Re: 入試の過去問を解いてみたのですが

#8

投稿記事 by Tatu » 4年前

コード:

#include <stdio.h>

double func( double X0 )
{
	//a,b,cは実数なのでintではなく、doubleの方がよい
	//全角スペースを除去
	double a=3.0; /*仮定*/
	double b=3.0; /*仮定*/
	double c=-3.0;/*仮定*/
	double E=0.000001 ; /* 自分で設定した許容誤差です。*/

	double X;

	//条件判定をしない
	while(1)
	{
		//分母を括弧でくくる必要がある
		//X = X0-(a*(X0-b)*(X0-b)+c)/(2*a*(X0-b));でもよい
		X = (-a*X0*X0+a*b*b+c)/(2*a*(b-X0)); /*接線のX切片の値*/
		//|X0-X|<E <=> -E<X0-X かつ X0-X<E
		//math.hをインクルードしてfabsを使って書いてもよい
		if(X0-X<E && X0-X>-E)
		{
			//Xは実数なので整数用の%dではなく、%lfを使用
			printf("%lf\n",X);
			return X ;
		}
		//前のX切片の値を記憶する。X=X0だと意味がない。
		X0=X;
	}
}
 
 
int main (void)
{       
	//bを3.0としているのでそれ以外を引数に入れる
	func(5.0);
	return 0;
}

morokosiQ

Re: 入試の過去問を解いてみたのですが

#9

投稿記事 by morokosiQ » 4年前

ありがとうございます!

解決しました!

閉鎖

“C言語何でも質問掲示板” へ戻る