- ベストアンサー
2次方程式の解
ax^2+bx+c=0の方程式について abcを自分で入力して、「2次方程式として成り立つか」の判断をし、2次方程式であればその解を求めるプログラムです。 2次方程式の解き方をなんとなく忘れていたので、数IIの教科書やらで確認してみました。 以下のように作成したのですが、解が出るはずの値を入力しても強制的に終了してしまいます。どこがおかしいのでしょうか? 他に気になる点は、メイン関数にて「2次方程式として成り立った場合」にはサブへ移動ができているのでしょうか。 あと、仮に↑が合っていたとして、異なる2つの虚数解の計算方法は以下のやり方でも良いのかどうかもお聞きしたいです。 よろしくお願いします。 #include<stdio.h> #include<math.h> void niji(double a,double b,double c){ double x1,x2,x3,y1,y2,D; D=b*b-(4.0)*a*c; if(D>0){ printf("2つの異なる実数解\n"); x1=(-b+sqrt(D))/(2.0*a); x2=(-b-sqrt(D))/(2.0*a); printf("x= %f , %f \n",x1,x2); } else if(D==0){ printf("重解\n"); x3=(-b)/(2.0*a); printf("x= %f \n",x3); } else{ printf("2つの異なる虚数解\n"); x3=(-b)/(2.0*a); y1=sqrt(D)/(2.0*a); y2=-sqrt(D)/(2.0*a); printf("x= %f + i %f, %f - i %f\n",x3,y1,x3,y2); } return; } int main(void){ double a,b,c; printf("ax^2+bx+c=0の式のabcを入力せよ\n"); while(scanf("%f %f %f",&a,&b,&c)){ if(a==b==c==0){ break; } else if((a==b==0)&&(c!=0)){ printf("不能\n"); } else if((a==0)&&(b!=0)){ printf("1次方程式になる\n"); } else{// 入力されたabcが↑の3つに該当しなければ niji(a,b,c);//←サブ関数に示した2次方程式を解く } } return 0; }
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
>printf("2つの異なる虚数解\n"); >x3=(-b)/(2.0*a); >y1=sqrt(D)/(2.0*a); >y2=-sqrt(D)/(2.0*a); ここでD<0なのでsqrt(D)がおかしくなります。 sqrt(-D)にしましょう >if(a==b==c==0){ は次のように解釈します if( ((a==b)==c)==0){ まず (a==b)を計算します。 Cでは、==などの比較演算は、成立つと「真」の意味で1,不成立だと「偽」の意味で0となります。 なのでaとbが同じなら1,違えば0です。 次に上の値を使って (a==b)==c を計算します。a==bは0か1です。 (a==b かつ c==1 ) なら1、 (a!=b かつ c==0 )なら1 そうでないなら (a==b) != c なので0です。 最後に、上の値を使って ((a==b)==c)==0 を計算します。上の結果から、ほとんどの場合は ((a==b)==c)は0ですから、ほとんどの場合で1となります。 したがって、ifの条件が成立し、breakが実行されます。 Cの場合、数学でよくある表記 a==b==c==0 とか、 a<b<c 等は、数学での意味と違う解釈をされる、とお考えください。 ( 唯一、変数への代入'a=b=c =0:a,b,cを0にする等)だけは使えます) 式を展開して (a==0) && (b==0) && ( c == 0 ) (a < b) && ( b < c ) と等と書く必要があります >else if((a==b==0)&&(c!=0)){ も同様です。
その他の回答 (2)
- asuncion
- ベストアンサー率33% (2127/6289)
>else if((a==0)&&(b!=0)){ >x1=-b/a; なぜ、-b/a なのでしょうか。
お礼
bx+c=0の間違えでした;;ケアレスミスです なので-c/bですね。 解決しました。ありがとうございます。
補足
式的には ax+b=0→ax=-b となるので x=-b/aになると判断しました。
- himajin100000
- ベストアンサー率54% (1660/3060)
一応VC++ 2008で期待通りの答えを返すように修正出来た。 俺はCの規格に詳しくないが 1.doubleをscanfでとるときは%fではなく%lfなのでは? 2.多分 ============================== 「代入演算子=」は、代入された値を返し、右から計算するので、 a = b = c = 0; → c = 0; a = b = 0; → c = 0; b = 0; a = 0; と結果が同じになる。 ====================== しかし、「比較演算子==」は、【代入された値を返すのではなく、】C++の場合はboolを返し、 Cの場合は多分int[falseの時は0,trueの時は0以外の値]を返すと思う。 a = 1; b = 2; c = 1; a == b == c == 0; (a == b) == c == 0; 0 == c == 0; 0 == 0; →真 →breakに引っかかって何も表示されない ===================== という二つを混同しているのではないかと思う
お礼
%fを%lfに直しました。 それと、(a==b==c==0)を(a==0)&&(b==0)&&(c==0)に変えてみたらできました。 まだほかにも疑問点はあるんですけどね。 一応その件は解決です。 ありがとうございます。
お礼
a,b,cが全て同じ場合の書き方に気をつけたいと思います。 虚数解の表示方法で y1=sqrt(-D)/(2.0*a); y2=sqrt(-D)/(2.0*a); でやってみたら上手くいきました。 ありがとうございます。
補足
疑問点があるので補足書きます。 結果が1次方程式となった場合の表示をさせたいと思ったのですが、プログラムは以下の通りです。どう改善すればよいでしょうか 例えばaに0, bに5, cに5を入れた場合、1次方程式になるので 解は-1のはずなのですが、結果が正しく出ません。 else if((a==0)&&(b!=0)){ x1=-b/a; printf("1次方程式で、答えは%fである\n",x1); }