2次方程式の解を求めるプログラム
内容自体は昨日やったことですけど、記事書いたのがネット時間*1外だったので、今日の記事にします。
なんだか、制御科の学生がわずか2時間のC++の講義の後に、そんなプログラムを作れ、という課題が出たらしいです。
2時間の講義でできることなんて、そんなに無いと思うんですけどねぇ。変数使って四則演算ぐらい?
解説もかなりテキトー*2だったらしいです。
で、こんな地味に難しい課題をプログラミング経験殆ど無しの人に出したと。なんという鬼畜。
簡単と思いきや意外と難しいと思うんですよね。平方根出すには関数必要だし。
そもそもC言語における関数がなんなのかイマイチ理解していない状態(ソース:友人)でそんなの無理だろ、と。
というわけで、暇なので(暇では無いが)そのプログラムを作ってみることにしました。
で、40分ほどで完成・・・したのかな?
折角なので人間様が手計算でやった時みたいにルートの記号使ってやりたかったのですが、素因数分解なんて高度なことC言語の基礎勉強中な私にはできないので断念しました。
とりあえず、2つの実数解(判別式D>0)、重解(D=0)のときの解を出すのは非常に簡単でした。
まぁ、単純に解の公式に当てはめてやればいいわけですからね。
問題は2つの虚数解(D<0)のとき。
最初は1つの変数の中に全部入れたかった*3んですが、やり方がわかならいので諦めました。
仕方がないので実数部分と虚数部分を分けて出力して、printfの間に+やらiやら混ぜて無理矢理再現しました。
ちょっと無理矢理過ぎるのでもうちょっと何とかしたい。
折角なので微妙すぎるソースも追記欄で晒しておきますね。
物凄い勢いで「こうしろ!」ってのがあったら是非コメント欄にお願いします。
#include <stdio.h> #include <math.h> int main(void){ int a,b,c,type=0; //a,b,cは二次方程式ax^2+bx+cの変数部分、typeは解の種類(0=実数解,1=虚数解,2=重解) double d,answer[2]; //dは平方根の中身、answerは2つの実数解、もしくは虚数解の実数部分(answer[0])と虚数部分(answer[1]) printf("ax^2+bx+c=0のa,b,cを入力してください\n"); printf("a=");scanf("%d",&a); printf("b=");scanf("%d",&b); printf("c=");scanf("%d",&c); d = b*b-4*a*c; //判別式D=b^2-4acを計算 if (d < 0){ //判別式が負の場合、type=1とし、平方根部分をプラスに変更する type++; d *=-1; } if (d == 0){ //判別式が0の場合、type=2とする。 type += 2; } switch(type){ case 0: //2つの実数解となる場合は平方根部分を求めて、解の公式に代入 d = sqrt(d); answer[0] = (double) (-1*b+d)/(2*a); answer[1] = (double) (-1*b-d)/(2*a); printf("解は%lfと%lfです。\n",answer[0],answer[1]); break; case 1: //2つの虚数解となる場合は実数部分と虚数部分を分けて出力 answer[0] = (double) (-1*b)/(2*a); //実数解部分 answer[1] = (double) sqrt(d)/(2*a); //虚数解部分 printf("解は%lf+%lfiと%lf-%lfiです。\n",answer[0],answer[1],answer[0],answer[1]); break; case 2: //重解となる場合は平方根部分は無視して計算 answer[0] = (-1*b)/(2*a); printf("解は%lfです。\n",answer[0]); break; } return(0); }
さっき、何故私は人の学科の宿題をやっているのだろう、と我に返りました。
まぁ、こうやって試行錯誤しながら考えていくのは楽しいので良いですけどね。