3

Fortran で最初のプログラムを試して、二次方程式を解こうとしています。コードを二重および三重にチェックしましたが、何も問題はありません。「(1)の名前に無効な文字」と「(1)の分類不能なステートメント」がさまざまな場所に表示され続けます。コードの何が問題になっていますか?

! This program solves quadratic equations
! of the form ax^2 + bx + c = 0.
! Record:
! Name:             Date:     Notes:
! Damon Robles      4/3/10    Original Code

PROGRAM quad_solv
IMPLICIT NONE

! Variables
REAL :: a, b, c
REAL :: discrim, root1, root2,    
COMPLEX :: comp1, comp2
CHARACTER(len=1) :: correct 

! Prompt user for coefficients.
WRITE(*,*) "This program solves quadratic equations "
WRITE(*,*) "of the form ax^2 + bx + c = 0. "
WRITE(*,*) "Please enter the coefficients a, b, and "
WRITE(*,*) "c, separated by commas:"
READ(*,*) a, b, c
WRITE(*,*) "Is this correct: a = ", a, " b = ", b
WRITE(*,*) " c = ", c, " [Y/N]? "
READ(*,*) correct
IF correct = N STOP
IF correct = Y THEN

! Definition
discrim = b**2 - 4*a*c

! Calculations
IF discrim > 0 THEN
root1 = (-b + sqrt(discrim))/(2*a)
root2 = (-b - sqrt(discrim))/(2*a)
WRITE(*,*) "This equation has two real roots. "
WRITE(*,*) "x1 = ", root1
WRITE(*,*) "x2 = ", root2
IF discrim = 0 THEN
root1 = -b/(2*a)
WRITE(*,*) "This equation has a double root. "
WRITE(*,*) "x1 = ", root1
IF discrim < 0 THEN
comp1 = (-b + sqrt(discrim))/(2*a)
comp2 = (-b - sqrt(discrim))/(2*a)
WRITE(*,*) "x1 = ", comp1
WRITE(*,*) "x2 = ", comp2

PROGRAM END quad_solv
4

4 に答える 4

2

redo 入力にループバックする方法に関する追加の質問 (Fortran >= 90 のループ機能を示すサンプル プログラム)について。また、プログラムをクラッシュさせる無効な入力が検出された場合に使用されるサイクル制御も示されています。(たとえば、数値の代わりに、最初の読み取りへの入力として「A」を入力します。) この場合、iostat 変数がゼロ以外の値を取得し、IF ステートメントがサイクルをアクティブにし、残りの DO ループが実行されます。スキップされ、ループが新たに循環します。

program test_readdata

real :: a, b, c
integer :: ReturnCode
character (len=1) :: correct

ReadData: do

   write (*, '( "This program solves quadratic equations of the form ax^2 + bx + c = 0. " )' ) 
   write (*, '( "Please enter the coefficients a, b, and c, separated by commas: " )', advance='no' )
   read (*,*, iostat=ReturnCode) a, b, c
   if ( ReturnCode /= 0 ) cycle ReadData
   write (*,*) "Is this correct: a = ", a, " b = ", b, " c = ", c
   write (*, '( "Enter Y or N: " )', advance='no' )
   read (*,*, iostat=ReturnCode) correct
   if ( ReturnCode /= 0 ) cycle ReadData
   if ( correct == 'Y'  .or.  correct == 'y' )  exit ReadData

end do ReadData

stop

end program test_readdata

私のおすすめの本: Metcalf、Reid、および Cohen によるFortran 95/2003 の説明。

于 2010-04-08T00:02:34.567 に答える
1

あなたのコードで最初に気付いたのは、プログラムの最後の構文エラーです。

END

プログラムという言葉の前に置くべきだった

エディターは構文エラーを強調表示しませんか?

ELF 90 の学生版はかなり安価に入手できるので、始めるのに適しています。次に、値の受け渡し経路を色分けする Visual Studio とアルゴリズム フロー チャート ジェネレーターを使用して、Lahey ELF 95 にアップグレードします。

于 2010-04-14T22:49:06.103 に答える
0

エラーが多すぎます... Fortran の基本を知らないようです...

最小限の修正で

! This program solves quadratic equations
! of the form ax^2 + bx + c = 0.
! Record:
! Name:             Date:     Notes:
! Damon Robles      4/3/10    Original Code

PROGRAM quad_solv

  IMPLICIT NONE

  ! Variables
  REAL :: a, b, c
  REAL :: discrim, root1, root2    
  COMPLEX :: comp1, comp2
  CHARACTER(len=1) :: correct 

  ! Prompt user for coefficients.
  WRITE(*,*) "This program solves quadratic equations "
  WRITE(*,*) "of the form ax^2 + bx + c = 0. "
  WRITE(*,*) "Please enter the coefficients a, b, and "
  WRITE(*,*) "c, separated by commas:"
  READ(*,*) a, b, c
  WRITE(*,*) "Is this correct: a = ", a, " b = ", b
  WRITE(*,*) " c = ", c, " [Y/N]? "
  READ(*,*) correct

  IF (correct == 'N') STOP

  IF (correct == 'Y') THEN

    ! Definition
    discrim = b**2 - 4*a*c

    ! Calculations
    IF (discrim > 0) THEN
      root1 = (-b + sqrt(discrim))/(2*a)
      root2 = (-b - sqrt(discrim))/(2*a)
      WRITE(*,*) "This equation has two real roots. "
      WRITE(*,*) "x1 = ", root1
      WRITE(*,*) "x2 = ", root2
    ELSEIF (discrim == 0) THEN
      root1 = -b/(2*a)
      WRITE(*,*) "This equation has a double root. "
      WRITE(*,*) "x1 = ", root1
    ELSE
      comp1 = (-b + sqrt(discrim))/(2*a)
      comp2 = (-b - sqrt(discrim))/(2*a)
      WRITE(*,*) "x1 = ", comp1
      WRITE(*,*) "x2 = ", comp2
    END IF

  END IF  

END PROGRAM quad_solv

PS私は正確さをチェックしませんでした。PPS 常にコードをインデントして読みやすくし、STOP ステートメントを使用しないでください。各プログラム (またはサブルーチン) には、1 つの入り口と 1 つの出口が必要です。STOP の唯一の適切な場所は、冗長な END PROGRAM ステートメントの直前です。したがって、STOP は使用しないでください。

于 2010-04-06T20:59:32.207 に答える
0

いくつかの変更: 正しい IF 構文。必要に応じて、定数を整数ではなく実数にする:

IF (CORRECT == "N" ) stop
if ( discrim > 0.0 ) then

追加の場所で適用すると、非常に近いはずです。幸運を。

浮動小数点数が正確な値を持っているかどうかをテストするのは、不十分なアルゴリズムになる可能性があります。丸め誤差によって disrim の値が 1.0E-30 になる場合、完全な算術演算では値がゼロになり、2 重根が示される場合はどうなるでしょうか?

于 2010-04-06T20:59:36.157 に答える