integer a, b, c real x1, x2 c read(5,*) a, b, c x1 = ( -b + sqrt( b*b - 4.0 * a * c ))/ (2.0*a) x2 = ( -b - sqrt( b*b - 4.0 * a * c ))/ (2.0*a) c write(6,*) x1, x2 c endいくつかの入力データに対してはきちんと結果を出してくれますが、そうは ならない場合があり、つまり上のプログラムには重要な欠陥がいくつかあり ます。
2.はIF文を使ってプログラムの流れを変えてやります。
解答2
real a, b, c real x1, x2 c read(5,*) a, b, c if( a .eq. 0.0 ) then x1 = - c / b x2 = 0.0 else x1 = ( -b + sqrt( b*b - 4.0*a*c ))/ ( 2.0*a ) x2 = ( -b - sqrt( b*b - 4.0*a*c ))/ ( 2.0*a ) end if c write(6,*) x1, x2 c end
3.も2.の場合と同様、IF文で解決させましょう。
解答3
real a, b, c real x1, x2 c read(5,*) a, b, c if( a .eq. 0.0 ) then x1 = - c / b c write(6,*) 'x1 = ', x1 c else if( (b*b-4.0*a*c) .lt. 0.0 ) then c write(6,*) '***** root is imaginary *****' c else x1 = ( -b + sqrt( b*b - 4.0*a*c ))/ ( 2.0*a ) x2 = ( -b - sqrt( b*b - 4.0*a*c ))/ ( 2.0*a ) c write(6,*) 'x1 = ', x1, ' x2 = ', x2 c end if c end
4.はちょっと理解しにくいですね。実は b の絶対値と b*b-4*a*c の平方根の絶対値 が近い値の時桁落ちが起きてしまいます。これを 避けるためには
x1 = (-b - (sgn(b))* sqrt(b*b-4*a*c))/ (2*a)ここで
sgn(b) = 1 (b>=0) or -1 (b<0)また他の解は解と係数の関係
x2 = c / (a*x1)から求める方が適切といえます。